<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
	<id>https://mediawiki.ajlsm.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jlarvers</id>
	<title>AJLSM - Contributions [fr]</title>
	<link rel="self" type="application/atom+xml" href="https://mediawiki.ajlsm.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jlarvers"/>
	<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/wiki/Sp%C3%A9cial:Contributions/Jlarvers"/>
	<updated>2026-11-06T18:07:56Z</updated>
	<subtitle>Contributions</subtitle>
	<generator>MediaWiki 1.46.2</generator>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=MediaWiki:Sidebar&amp;diff=6532</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=MediaWiki:Sidebar&amp;diff=6532"/>
		<updated>2026-11-06T12:54:48Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : Ajout liens pages spéciales&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* Accès Rapide&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** special:allpages|Toutes les pages&lt;br /&gt;
&amp;lt;!-- ** randompage-url|randompage --&amp;gt;&lt;br /&gt;
** Special:Categories|Catégories (toutes)&lt;br /&gt;
** Special:Toutes_les_pages/template:!|Modèles (toutes)&lt;br /&gt;
&lt;br /&gt;
* Autres&lt;br /&gt;
&amp;lt;!-- ** mainpage|mainpage-description --&amp;gt;&lt;br /&gt;
&amp;lt;!-- ** currentevents-url|currentevents --&amp;gt;&lt;br /&gt;
&amp;lt;!-- ** portal-url|portal --&amp;gt;&lt;br /&gt;
** helppage|help&lt;br /&gt;
** Special:UserLogin|Créer un utilisateur&lt;br /&gt;
&lt;br /&gt;
* administration&lt;br /&gt;
** Special:SpecialPages|Pages spéciales&lt;br /&gt;
** Special:Version|Version de MediaWiki&lt;br /&gt;
** Special:UserRights|Droits des utilisateurs&lt;br /&gt;
** Special:CreateForm|Créer un formulaire&lt;br /&gt;
&lt;br /&gt;
* SEARCH&lt;br /&gt;
&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
&amp;lt;!-- * LANGUAGES --&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=MediaWiki:AJLSM-WikiEditor.js&amp;diff=6531</id>
		<title>MediaWiki:AJLSM-WikiEditor.js</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=MediaWiki:AJLSM-WikiEditor.js&amp;diff=6531"/>
		<updated>2026-11-06T12:30:22Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : Restauration des 14 boutons historiques AJLSM&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
/*&lt;br /&gt;
 * AJLSM - Barre d&#039;outils WikiEditor&lt;br /&gt;
 * Migration MediaWiki 1.18.2 vers 1.46.2&lt;br /&gt;
 * 14 boutons historiques, sans modification de l&#039;extension.&lt;br /&gt;
 */&lt;br /&gt;
mw.hook( &#039;wikiEditor.toolbarReady&#039; ).add( function ( $textarea ) {&lt;br /&gt;
&lt;br /&gt;
    var imageBase = mw.config.get( &#039;wgScriptPath&#039; ) + &#039;/images/&#039;;&lt;br /&gt;
&lt;br /&gt;
    function bouton( label, icon, pre, peri, post ) {&lt;br /&gt;
        return {&lt;br /&gt;
            label: label,&lt;br /&gt;
            type: &#039;button&#039;,&lt;br /&gt;
            icon: imageBase + icon,&lt;br /&gt;
            action: {&lt;br /&gt;
                type: &#039;encapsulate&#039;,&lt;br /&gt;
                options: {&lt;br /&gt;
                    pre: pre,&lt;br /&gt;
                    peri: peri,&lt;br /&gt;
                    post: post&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        };&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Onglet AJLSM&lt;br /&gt;
    $textarea.wikiEditor( &#039;addToToolbar&#039;, {&lt;br /&gt;
        sections: {&lt;br /&gt;
            ajlsm: {&lt;br /&gt;
                type: &#039;toolbar&#039;,&lt;br /&gt;
                label: &#039;AJLSM&#039;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    // Groupe de boutons&lt;br /&gt;
    $textarea.wikiEditor( &#039;addToToolbar&#039;, {&lt;br /&gt;
        section: &#039;ajlsm&#039;,&lt;br /&gt;
        groups: {&lt;br /&gt;
            insertion: {&lt;br /&gt;
                label: &#039;Insertion&#039;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    // Les 14 boutons historiques&lt;br /&gt;
    $textarea.wikiEditor( &#039;addToToolbar&#039;, {&lt;br /&gt;
        section: &#039;ajlsm&#039;,&lt;br /&gt;
        group: &#039;insertion&#039;,&lt;br /&gt;
        tools: {&lt;br /&gt;
&lt;br /&gt;
            ajlsmRef: bouton(&lt;br /&gt;
                &#039;Insérer une référence&#039;,&lt;br /&gt;
                &#039;7/73/Toolbar-ref.png&#039;,&lt;br /&gt;
                &#039;&amp;lt;ref&amp;gt;&#039;,&lt;br /&gt;
                &#039;texte de la référence&#039;,&lt;br /&gt;
                &#039;&amp;lt;/ref&amp;gt;&#039;&lt;br /&gt;
            ),&lt;br /&gt;
&lt;br /&gt;
            ajlsmReferences: bouton(&lt;br /&gt;
                &#039;Insérer la liste des références&#039;,&lt;br /&gt;
                &#039;8/8d/Toolbar-references.png&#039;,&lt;br /&gt;
                &#039;== Références ==\n&amp;lt;references/&amp;gt;&#039;,&lt;br /&gt;
                &#039;&#039;,&lt;br /&gt;
                &#039;&#039;&lt;br /&gt;
            ),&lt;br /&gt;
&lt;br /&gt;
            ajlsmCategory: bouton(&lt;br /&gt;
                &#039;Ajouter une catégorie&#039;,&lt;br /&gt;
                &#039;c/c4/Toolbar_category.png&#039;,&lt;br /&gt;
                &#039;[[category:&#039;,&lt;br /&gt;
                &amp;quot;catégorie à laquelle appartient l&#039;article&amp;quot;,&lt;br /&gt;
                &#039;]]&#039;&lt;br /&gt;
            ),&lt;br /&gt;
&lt;br /&gt;
            ajlsmVar: bouton(&lt;br /&gt;
                &#039;Insérer une variable&#039;,&lt;br /&gt;
                &#039;2/24/Toolbar-var.svg&#039;,&lt;br /&gt;
                &#039;{{var|&#039;,&lt;br /&gt;
                &#039;maVariable&#039;,&lt;br /&gt;
                &#039;}}&#039;&lt;br /&gt;
            ),&lt;br /&gt;
&lt;br /&gt;
            ajlsmPath: bouton(&lt;br /&gt;
                &#039;Ajouter un chemin vers un fichier/dossier&#039;,&lt;br /&gt;
                &#039;9/96/Toolbar-path.svg&#039;,&lt;br /&gt;
                &#039;{{path|&#039;,&lt;br /&gt;
                &#039;/path/to/dir-or-file&#039;,&lt;br /&gt;
                &#039;}}&#039;&lt;br /&gt;
            ),&lt;br /&gt;
&lt;br /&gt;
            ajlsmSyntaxHighlight: bouton(&lt;br /&gt;
                &#039;Insérer un bloc de code&#039;,&lt;br /&gt;
                &#039;1/16/Toolbar-code.svg&#039;,&lt;br /&gt;
                &#039;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;\n&#039;,&lt;br /&gt;
                &amp;quot;echo $(date &#039;+%Y-%b-%d&#039;) # affiche la date en BASH&amp;quot;,&lt;br /&gt;
                &#039;\n&amp;lt;/syntaxhighlight&amp;gt;&#039;&lt;br /&gt;
            ),&lt;br /&gt;
&lt;br /&gt;
            ajlsmRemarque: bouton(&lt;br /&gt;
                &#039;Insérer une remarque&#039;,&lt;br /&gt;
                &#039;6/6d/Toolbar-remarque.svg&#039;,&lt;br /&gt;
                &#039;{{remarque|&#039;,&lt;br /&gt;
                &#039;remarque sur le paragraphe précédent/suivant (à vous de préciser)&#039;,&lt;br /&gt;
                &#039;}}&#039;&lt;br /&gt;
            ),&lt;br /&gt;
&lt;br /&gt;
            ajlsmImportant: bouton(&lt;br /&gt;
                &#039;Insérer une remarque importante&#039;,&lt;br /&gt;
                &#039;8/89/Important.svg&#039;,&lt;br /&gt;
                &#039;{{important|&#039;,&lt;br /&gt;
                &#039;remarque IMPORTANTE sur le paragraphe précédent/suivant (à vous de préciser)&#039;,&lt;br /&gt;
                &#039;}}&#039;&lt;br /&gt;
            ),&lt;br /&gt;
&lt;br /&gt;
            ajlsmNotice: bouton(&lt;br /&gt;
                &#039;Insérer une notice&#039;,&lt;br /&gt;
                &#039;0/02/Notice.svg&#039;,&lt;br /&gt;
                &#039;{{notice|&#039;,&lt;br /&gt;
                &#039;notice sur le paragraphe précédent/suivant (à vous de préciser)&#039;,&lt;br /&gt;
                &#039;}}&#039;&lt;br /&gt;
            ),&lt;br /&gt;
&lt;br /&gt;
            ajlsmTodo: bouton(&lt;br /&gt;
                &#039;Insérer une tâche à faire&#039;,&lt;br /&gt;
                &#039;2/25/Todo.svg&#039;,&lt;br /&gt;
                &#039;{{todo|&#039;,&lt;br /&gt;
                &#039;todo sur le paragraphe précédent/suivant (à vous de préciser)&#039;,&lt;br /&gt;
                &#039;}}&#039;&lt;br /&gt;
            ),&lt;br /&gt;
&lt;br /&gt;
            ajlsmCmd: bouton(&lt;br /&gt;
                &#039;Insérer une commande shell&#039;,&lt;br /&gt;
                &#039;8/84/Toolbar-shell.svg&#039;,&lt;br /&gt;
                &#039;{{cmd|&#039;,&lt;br /&gt;
                &#039;commande, option ou flag (-h, -v, etc.)&#039;,&lt;br /&gt;
                &#039;}}&#039;&lt;br /&gt;
            ),&lt;br /&gt;
&lt;br /&gt;
            ajlsmXmlTag: bouton(&lt;br /&gt;
                &#039;Insérer une balise XML&#039;,&lt;br /&gt;
                &#039;c/c8/Toolbar-XML-tag.svg&#039;,&lt;br /&gt;
                &#039;{{tag|&#039;,&lt;br /&gt;
                &#039;élément XML (les &amp;lt; &amp;gt; sont ajouté automatiquement)&#039;,&lt;br /&gt;
                &#039;}}&#039;&lt;br /&gt;
            ),&lt;br /&gt;
&lt;br /&gt;
            ajlsmXmlAttr: bouton(&lt;br /&gt;
                &#039;Insérer un attribut XML&#039;,&lt;br /&gt;
                &#039;1/13/Toolbar-XML-attr.svg&#039;,&lt;br /&gt;
                &#039;{{attr|&#039;,&lt;br /&gt;
                &amp;quot;nom de l&#039;attribut XML (il sera @préfixé)&amp;quot;,&lt;br /&gt;
                &#039;}}&#039;&lt;br /&gt;
            ),&lt;br /&gt;
&lt;br /&gt;
            ajlsmValue: bouton(&lt;br /&gt;
                &#039;Insérer une valeur&#039;,&lt;br /&gt;
                &#039;4/4d/Toolbar-value.svg&#039;,&lt;br /&gt;
                &#039;{{value|&#039;,&lt;br /&gt;
                &#039;maValue&#039;,&lt;br /&gt;
                &#039;}}&#039;&lt;br /&gt;
            )&lt;br /&gt;
        }&lt;br /&gt;
    } );&lt;br /&gt;
} );&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=MediaWiki:AJLSM-WikiEditor.js&amp;diff=6530</id>
		<title>MediaWiki:AJLSM-WikiEditor.js</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=MediaWiki:AJLSM-WikiEditor.js&amp;diff=6530"/>
		<updated>2026-11-06T12:28:43Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : Création de l&amp;#039;onglet AJLSM dans WikiEditor&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
mw.hook( &#039;wikiEditor.toolbarReady&#039; ).add( function ( $textarea ) {&lt;br /&gt;
    $textarea.wikiEditor( &#039;addToToolbar&#039;, {&lt;br /&gt;
        sections: {&lt;br /&gt;
            ajlsm: {&lt;br /&gt;
                type: &#039;toolbar&#039;,&lt;br /&gt;
                label: &#039;AJLSM&#039;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    $textarea.wikiEditor( &#039;addToToolbar&#039;, {&lt;br /&gt;
        section: &#039;ajlsm&#039;,&lt;br /&gt;
        groups: {&lt;br /&gt;
            insertion: {&lt;br /&gt;
                label: &#039;Insertion&#039;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    $textarea.wikiEditor( &#039;addToToolbar&#039;, {&lt;br /&gt;
        section: &#039;ajlsm&#039;,&lt;br /&gt;
        group: &#039;insertion&#039;,&lt;br /&gt;
        tools: {&lt;br /&gt;
            ajlsmPath: {&lt;br /&gt;
                label: &#039;Ajouter un chemin vers un fichier/dossier&#039;,&lt;br /&gt;
                type: &#039;button&#039;,&lt;br /&gt;
                icon: mw.config.get( &#039;wgScriptPath&#039; ) + &#039;/images/9/96/Toolbar-path.svg&#039;,&lt;br /&gt;
                action: {&lt;br /&gt;
                    type: &#039;encapsulate&#039;,&lt;br /&gt;
                    options: {&lt;br /&gt;
                        pre: &#039;{{path|&#039;,&lt;br /&gt;
                        peri: &#039;/path/to/dir-or-file&#039;,&lt;br /&gt;
                        post: &#039;}}&#039;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    } );&lt;br /&gt;
} );&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=MediaWiki:Common.js&amp;diff=6529</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=MediaWiki:Common.js&amp;diff=6529"/>
		<updated>2026-11-06T12:25:20Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/**&lt;br /&gt;
 * Keep code in MediaWiki:Common.js to a minimum as it is unconditionally&lt;br /&gt;
 * loaded for all users on every wiki page. If possible create a gadget that is&lt;br /&gt;
 * enabled by default instead of adding it here (since gadgets are fully&lt;br /&gt;
 * optimized ResourceLoader modules with possibility to add dependencies etc.)&lt;br /&gt;
 *&lt;br /&gt;
 * Since Common.js isn&#039;t a gadget, there is no place to declare its&lt;br /&gt;
 * dependencies, so we have to lazy load them with mw.loader.using on demand and&lt;br /&gt;
 * then execute the rest in the callback. In most cases these dependencies will&lt;br /&gt;
 * be loaded (or loading) already and the callback will not be delayed. In case a&lt;br /&gt;
 * dependency hasn&#039;t arrived yet it&#039;ll make sure those are loaded before this.&lt;br /&gt;
 */&lt;br /&gt;
/*global mw, $, importStylesheet, importScript */&lt;br /&gt;
/*jshint curly:false eqnull:true, strict:false, browser:true, */&lt;br /&gt;
mw.loader.using( [&#039;mediawiki.util&#039;, &#039;mediawiki.notify&#039;, &#039;jquery.client&#039;], function () {&lt;br /&gt;
/* Begin of mw.loader.using callback */&lt;br /&gt;
 &lt;br /&gt;
/**&lt;br /&gt;
 * Main Page layout fixes&lt;br /&gt;
 *&lt;br /&gt;
 * Description: Adds an additional link to the complete list of languages available.&lt;br /&gt;
 * Maintainers: [[User:AzaToth]], [[User:R. Koot]], [[User:Alex Smotrov]]&lt;br /&gt;
 */&lt;br /&gt;
if ( mw.config.get( &#039;wgPageName&#039; ) === &#039;Main_Page&#039; || mw.config.get( &#039;wgPageName&#039; ) === &#039;Talk:Main_Page&#039; ) {&lt;br /&gt;
    $( document ).ready( function () {&lt;br /&gt;
        mw.util.addPortletLink( &#039;p-lang&#039;, &#039;//meta.wikimedia.org/wiki/List_of_Wikipedias&#039;,&lt;br /&gt;
            &#039;Complete list&#039;, &#039;interwiki-completelist&#039;, &#039;Complete list of Wikipedias&#039; );&lt;br /&gt;
    } );&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
/**&lt;br /&gt;
 * Redirect User:Name/skin.js and skin.css to the current skin&#039;s pages&lt;br /&gt;
 * (unless the &#039;skin&#039; page really exists)&lt;br /&gt;
 * @source: http://www.mediawiki.org/wiki/Snippets/Redirect_skin.js&lt;br /&gt;
 * @rev: 2&lt;br /&gt;
 */&lt;br /&gt;
if ( mw.config.get( &#039;wgArticleId&#039; ) === 0 &amp;amp;&amp;amp; mw.config.get( &#039;wgNamespaceNumber&#039; ) === 2 ) {&lt;br /&gt;
    var titleParts = mw.config.get( &#039;wgPageName&#039; ).split( &#039;/&#039; );&lt;br /&gt;
    /* Make sure there was a part before and after the slash&lt;br /&gt;
       and that the latter is &#039;skin.js&#039; or &#039;skin.css&#039; */&lt;br /&gt;
    if ( titleParts.length == 2 ) {&lt;br /&gt;
        var userSkinPage = titleParts.shift() + &#039;/&#039; + mw.config.get( &#039;skin&#039; );&lt;br /&gt;
        if ( titleParts.slice( -1 ) == &#039;skin.js&#039; ) {&lt;br /&gt;
            window.location.href = mw.util.wikiGetlink( userSkinPage + &#039;.js&#039; );&lt;br /&gt;
        } else if ( titleParts.slice( -1 ) == &#039;skin.css&#039; ) {&lt;br /&gt;
            window.location.href = mw.util.wikiGetlink( userSkinPage + &#039;.css&#039; );&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
/**&lt;br /&gt;
 * Map addPortletLink to mw.util &lt;br /&gt;
 *&lt;br /&gt;
 * @deprecated: Use mw.util.addPortletLink instead.&lt;br /&gt;
 */&lt;br /&gt;
window.addPortletLink = function () {&lt;br /&gt;
    return mw.util.addPortletLink.apply( mw.util, arguments );&lt;br /&gt;
};&lt;br /&gt;
 &lt;br /&gt;
/**&lt;br /&gt;
 * Extract a URL parameter from the current URL&lt;br /&gt;
 *&lt;br /&gt;
 * @deprecated: Use mw.util.getParamValue with proper escaping&lt;br /&gt;
 */&lt;br /&gt;
window.getURLParamValue = function () {&lt;br /&gt;
    return mw.util.getParamValue.apply( mw.util, arguments );&lt;br /&gt;
};&lt;br /&gt;
 &lt;br /&gt;
/** &lt;br /&gt;
 * Test if an element has a certain class&lt;br /&gt;
 *&lt;br /&gt;
 * @deprecated:  Use $(element).hasClass() instead.&lt;br /&gt;
 */&lt;br /&gt;
window.hasClass = function ( element, className ) {&lt;br /&gt;
    return $( element ).hasClass( className );&lt;br /&gt;
};&lt;br /&gt;
 &lt;br /&gt;
/**&lt;br /&gt;
 * @source www.mediawiki.org/wiki/Snippets/Load_JS_and_CSS_by_URL&lt;br /&gt;
 * @rev 5&lt;br /&gt;
 */&lt;br /&gt;
// CSS&lt;br /&gt;
var extraCSS = mw.util.getParamValue( &#039;withCSS&#039; );&lt;br /&gt;
if ( extraCSS ) {&lt;br /&gt;
	if ( extraCSS.match( /^MediaWiki:[^&amp;amp;&amp;lt;&amp;gt;=%#]*\.css$/ ) ) {&lt;br /&gt;
		importStylesheet( extraCSS );&lt;br /&gt;
	} else {&lt;br /&gt;
		mw.notify( &#039;Only pages from the MediaWiki namespace are allowed.&#039;, { title: &#039;Invalid withCSS value&#039; } );&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
// JS&lt;br /&gt;
var extraJS = mw.util.getParamValue( &#039;withJS&#039; );&lt;br /&gt;
if ( extraJS ) {&lt;br /&gt;
	if ( extraJS.match( /^MediaWiki:[^&amp;amp;&amp;lt;&amp;gt;=%#]*\.js$/ ) ) {&lt;br /&gt;
		importScript( extraJS );&lt;br /&gt;
	} else {&lt;br /&gt;
		mw.notify( &#039;Only pages from the MediaWiki namespace are allowed.&#039;, { title: &#039;Invalid withJS value&#039; } );&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
/**&lt;br /&gt;
 * Import more specific scripts if necessary&lt;br /&gt;
 */&lt;br /&gt;
if ( mw.config.get( &#039;wgAction&#039; ) === &#039;edit&#039; || mw.config.get( &#039;wgAction&#039; ) === &#039;submit&#039; || mw.config.get( &#039;wgCanonicalSpecialPageName&#039; ) === &#039;Upload&#039; ) {&lt;br /&gt;
    /* scripts specific to editing pages */&lt;br /&gt;
    importScript( &#039;MediaWiki:Common.js/edit.js&#039; );&lt;br /&gt;
} else if ( mw.config.get( &#039;wgCanonicalSpecialPageName&#039; ) === &#039;Watchlist&#039; ) {&lt;br /&gt;
    /* watchlist scripts */&lt;br /&gt;
    importScript( &#039;MediaWiki:Common.js/watchlist.js&#039; );&lt;br /&gt;
}&lt;br /&gt;
if ( mw.config.get( &#039;wgNamespaceNumber&#039; ) === 6 ) {&lt;br /&gt;
    /* file description page scripts */&lt;br /&gt;
    importScript( &#039;MediaWiki:Common.js/file.js&#039; );&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
/**&lt;br /&gt;
 * Load scripts specific to Internet Explorer&lt;br /&gt;
 */&lt;br /&gt;
if ( $.client.profile().name === &#039;msie&#039; ) {&lt;br /&gt;
    importScript( &#039;MediaWiki:Common.js/IEFixes.js&#039; );&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
/**&lt;br /&gt;
 * Fix for Windows XP Unicode font rendering&lt;br /&gt;
 */&lt;br /&gt;
if ( navigator.appVersion.search(/windows nt 5/i) !== -1 ) {&lt;br /&gt;
    mw.util.addCSS( &#039;.IPA { font-family: &amp;quot;Lucida Sans Unicode&amp;quot;, &amp;quot;Arial Unicode MS&amp;quot;; } &#039; + &lt;br /&gt;
                &#039;.Unicode { font-family: &amp;quot;Arial Unicode MS&amp;quot;, &amp;quot;Lucida Sans Unicode&amp;quot;; } &#039; );&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
/**&lt;br /&gt;
 * WikiMiniAtlas&lt;br /&gt;
 *&lt;br /&gt;
 * Description: WikiMiniAtlas is a popup click and drag world map.&lt;br /&gt;
 *              This script causes all of our coordinate links to display the WikiMiniAtlas popup button.&lt;br /&gt;
 *              The script itself is located on meta because it is used by many projects.&lt;br /&gt;
 *              See [[Meta:WikiMiniAtlas]] for more information. &lt;br /&gt;
 * Maintainers: [[User:Dschwen]]&lt;br /&gt;
 */&lt;br /&gt;
( function () {&lt;br /&gt;
    var require_wikiminiatlas = false;&lt;br /&gt;
    var coord_filter = /geohack/;&lt;br /&gt;
    $( document ).ready( function() {&lt;br /&gt;
        $( &#039;a.external.text&#039; ).each( function( key, link ) {&lt;br /&gt;
            if ( link.href &amp;amp;&amp;amp; coord_filter.exec( link.href ) ) {&lt;br /&gt;
                require_wikiminiatlas = true;&lt;br /&gt;
                // break from loop&lt;br /&gt;
                return false;&lt;br /&gt;
            }&lt;br /&gt;
        } );&lt;br /&gt;
        if ( $( &#039;div.kmldata&#039; ).length ) {&lt;br /&gt;
            require_wikiminiatlas = true;&lt;br /&gt;
        }&lt;br /&gt;
        if ( require_wikiminiatlas ) {&lt;br /&gt;
            mw.loader.load( &#039;//meta.wikimedia.org/w/index.php?title=MediaWiki:Wikiminiatlas.js&amp;amp;action=raw&amp;amp;ctype=text/javascript&#039; );&lt;br /&gt;
        }&lt;br /&gt;
    } );&lt;br /&gt;
} )();&lt;br /&gt;
 &lt;br /&gt;
/**&lt;br /&gt;
 * Interwiki links to featured articles ***************************************&lt;br /&gt;
 *&lt;br /&gt;
 * Description: Highlights interwiki links to featured articles (or&lt;br /&gt;
 *              equivalents) by changing the bullet before the interwiki link&lt;br /&gt;
 *              into a star.&lt;br /&gt;
 * Maintainers: [[User:R. Koot]]&lt;br /&gt;
 */&lt;br /&gt;
function LinkFA() {&lt;br /&gt;
    if ( document.getElementById( &#039;p-lang&#039; ) ) {&lt;br /&gt;
        var InterwikiLinks = document.getElementById( &#039;p-lang&#039; ).getElementsByTagName( &#039;li&#039; );&lt;br /&gt;
 &lt;br /&gt;
        for ( var i = 0; i &amp;lt; InterwikiLinks.length; i++ ) {&lt;br /&gt;
            if ( document.getElementById( InterwikiLinks[i].className + &#039;-fa&#039; ) ) {&lt;br /&gt;
                InterwikiLinks[i].className += &#039; FA&#039;;&lt;br /&gt;
                InterwikiLinks[i].title = &#039;This is a featured article in another language.&#039;;&lt;br /&gt;
            } else if ( document.getElementById( InterwikiLinks[i].className + &#039;-ga&#039; ) ) {&lt;br /&gt;
                InterwikiLinks[i].className += &#039; GA&#039;;&lt;br /&gt;
                InterwikiLinks[i].title = &#039;This is a good article in another language.&#039;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
$( LinkFA );&lt;br /&gt;
 &lt;br /&gt;
/**&lt;br /&gt;
 * Collapsible tables *********************************************************&lt;br /&gt;
 *&lt;br /&gt;
 * Description: Allows tables to be collapsed, showing only the header. See&lt;br /&gt;
 *              [[Wikipedia:NavFrame]].&lt;br /&gt;
 * Maintainers: [[User:R. Koot]]&lt;br /&gt;
 */&lt;br /&gt;
 &lt;br /&gt;
var autoCollapse = 2;&lt;br /&gt;
var collapseCaption = &#039;hide&#039;;&lt;br /&gt;
var expandCaption = &#039;show&#039;;&lt;br /&gt;
 &lt;br /&gt;
window.collapseTable = function ( tableIndex ) {&lt;br /&gt;
    var Button = document.getElementById( &#039;collapseButton&#039; + tableIndex );&lt;br /&gt;
    var Table = document.getElementById( &#039;collapsibleTable&#039; + tableIndex );&lt;br /&gt;
 &lt;br /&gt;
    if ( !Table || !Button ) {&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    var Rows = Table.rows;&lt;br /&gt;
    var i;&lt;br /&gt;
 &lt;br /&gt;
    if ( Button.firstChild.data === collapseCaption ) {&lt;br /&gt;
        for ( i = 1; i &amp;lt; Rows.length; i++ ) {&lt;br /&gt;
            Rows[i].style.display = &#039;none&#039;;&lt;br /&gt;
        }&lt;br /&gt;
        Button.firstChild.data = expandCaption;&lt;br /&gt;
    } else {&lt;br /&gt;
        for ( i = 1; i &amp;lt; Rows.length; i++ ) {&lt;br /&gt;
            Rows[i].style.display = Rows[0].style.display;&lt;br /&gt;
        }&lt;br /&gt;
        Button.firstChild.data = collapseCaption;&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
 &lt;br /&gt;
function createCollapseButtons() {&lt;br /&gt;
    var tableIndex = 0;&lt;br /&gt;
    var NavigationBoxes = {};&lt;br /&gt;
    var Tables = document.getElementsByTagName( &#039;table&#039; );&lt;br /&gt;
    var i;&lt;br /&gt;
 &lt;br /&gt;
    function handleButtonLink( index, e ) {&lt;br /&gt;
        window.collapseTable( index );&lt;br /&gt;
        e.preventDefault();&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    for ( i = 0; i &amp;lt; Tables.length; i++ ) {&lt;br /&gt;
        if ( $( Tables[i] ).hasClass( &#039;collapsible&#039; ) ) {&lt;br /&gt;
 &lt;br /&gt;
            /* only add button and increment count if there is a header row to work with */&lt;br /&gt;
            var HeaderRow = Tables[i].getElementsByTagName( &#039;tr&#039; )[0];&lt;br /&gt;
            if ( !HeaderRow ) continue;&lt;br /&gt;
            var Header = HeaderRow.getElementsByTagName( &#039;th&#039; )[0];&lt;br /&gt;
            if ( !Header ) continue;&lt;br /&gt;
 &lt;br /&gt;
            NavigationBoxes[ tableIndex ] = Tables[i];&lt;br /&gt;
            Tables[i].setAttribute( &#039;id&#039;, &#039;collapsibleTable&#039; + tableIndex );&lt;br /&gt;
 &lt;br /&gt;
            var Button     = document.createElement( &#039;span&#039; );&lt;br /&gt;
            var ButtonLink = document.createElement( &#039;a&#039; );&lt;br /&gt;
            var ButtonText = document.createTextNode( collapseCaption );&lt;br /&gt;
 &lt;br /&gt;
            Button.className = &#039;collapseButton&#039;;  /* Styles are declared in Common.css */&lt;br /&gt;
 &lt;br /&gt;
            ButtonLink.style.color = Header.style.color;&lt;br /&gt;
            ButtonLink.setAttribute( &#039;id&#039;, &#039;collapseButton&#039; + tableIndex );&lt;br /&gt;
            ButtonLink.setAttribute( &#039;href&#039;, &#039;#&#039; );&lt;br /&gt;
            $( ButtonLink ).on( &#039;click&#039;, $.proxy( handleButtonLink, ButtonLink, tableIndex ) );&lt;br /&gt;
            ButtonLink.appendChild( ButtonText );&lt;br /&gt;
 &lt;br /&gt;
            Button.appendChild( document.createTextNode( &#039;[&#039; ) );&lt;br /&gt;
            Button.appendChild( ButtonLink );&lt;br /&gt;
            Button.appendChild( document.createTextNode( &#039;]&#039; ) );&lt;br /&gt;
 &lt;br /&gt;
            Header.insertBefore( Button, Header.firstChild );&lt;br /&gt;
            tableIndex++;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    for ( i = 0;  i &amp;lt; tableIndex; i++ ) {&lt;br /&gt;
        if ( $( NavigationBoxes[i] ).hasClass( &#039;collapsed&#039; ) || ( tableIndex &amp;gt;= autoCollapse &amp;amp;&amp;amp; $( NavigationBoxes[i] ).hasClass( &#039;autocollapse&#039; ) ) ) {&lt;br /&gt;
            window.collapseTable( i );&lt;br /&gt;
        } &lt;br /&gt;
        else if ( $( NavigationBoxes[i] ).hasClass ( &#039;innercollapse&#039; ) ) {&lt;br /&gt;
            var element = NavigationBoxes[i];&lt;br /&gt;
            while ((element = element.parentNode)) {&lt;br /&gt;
                if ( $( element ).hasClass( &#039;outercollapse&#039; ) ) {&lt;br /&gt;
                    window.collapseTable ( i );&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
$( createCollapseButtons );&lt;br /&gt;
 &lt;br /&gt;
/**&lt;br /&gt;
 * Dynamic Navigation Bars (experimental)&lt;br /&gt;
 *&lt;br /&gt;
 * Description: See [[Wikipedia:NavFrame]].&lt;br /&gt;
 * Maintainers: UNMAINTAINED&lt;br /&gt;
 */&lt;br /&gt;
 &lt;br /&gt;
/* set up the words in your language */&lt;br /&gt;
var NavigationBarHide = &#039;[&#039; + collapseCaption + &#039;]&#039;;&lt;br /&gt;
var NavigationBarShow = &#039;[&#039; + expandCaption + &#039;]&#039;;&lt;br /&gt;
 &lt;br /&gt;
/**&lt;br /&gt;
 * Shows and hides content and picture (if available) of navigation bars&lt;br /&gt;
 * Parameters:&lt;br /&gt;
 *     indexNavigationBar: the index of navigation bar to be toggled&lt;br /&gt;
 **/&lt;br /&gt;
window.toggleNavigationBar = function ( indexNavigationBar, event ) {&lt;br /&gt;
    var NavToggle = document.getElementById( &#039;NavToggle&#039; + indexNavigationBar );&lt;br /&gt;
    var NavFrame = document.getElementById( &#039;NavFrame&#039; + indexNavigationBar );&lt;br /&gt;
    var NavChild;&lt;br /&gt;
 &lt;br /&gt;
    if ( !NavFrame || !NavToggle ) {&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    /* if shown now */&lt;br /&gt;
    if ( NavToggle.firstChild.data === NavigationBarHide ) {&lt;br /&gt;
        for ( NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling ) {&lt;br /&gt;
            if ( $( NavChild ).hasClass( &#039;NavContent&#039; ) || $( NavChild ).hasClass( &#039;NavPic&#039; ) ) {&lt;br /&gt;
                NavChild.style.display = &#039;none&#039;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    NavToggle.firstChild.data = NavigationBarShow;&lt;br /&gt;
 &lt;br /&gt;
    /* if hidden now */&lt;br /&gt;
    } else if ( NavToggle.firstChild.data === NavigationBarShow ) {&lt;br /&gt;
        for ( NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling ) {&lt;br /&gt;
            if ( $( NavChild ).hasClass( &#039;NavContent&#039; ) || $( NavChild ).hasClass( &#039;NavPic&#039; ) ) {&lt;br /&gt;
                NavChild.style.display = &#039;block&#039;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        NavToggle.firstChild.data = NavigationBarHide;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    event.preventDefault();&lt;br /&gt;
};&lt;br /&gt;
 &lt;br /&gt;
/* adds show/hide-button to navigation bars */&lt;br /&gt;
function createNavigationBarToggleButton() {&lt;br /&gt;
    var indexNavigationBar = 0;&lt;br /&gt;
    var NavFrame;&lt;br /&gt;
    var NavChild;&lt;br /&gt;
    /* iterate over all &amp;lt; div &amp;gt;-elements */&lt;br /&gt;
    var divs = document.getElementsByTagName( &#039;div&#039; );&lt;br /&gt;
    for ( var i = 0; (NavFrame = divs[i]); i++ ) {&lt;br /&gt;
        /* if found a navigation bar */&lt;br /&gt;
        if ( $( NavFrame ).hasClass( &#039;NavFrame&#039; ) ) {&lt;br /&gt;
 &lt;br /&gt;
            indexNavigationBar++;&lt;br /&gt;
            var NavToggle = document.createElement( &#039;a&#039; );&lt;br /&gt;
            NavToggle.className = &#039;NavToggle&#039;;&lt;br /&gt;
            NavToggle.setAttribute( &#039;id&#039;, &#039;NavToggle&#039; + indexNavigationBar );&lt;br /&gt;
            NavToggle.setAttribute( &#039;href&#039;, &#039;#&#039; );&lt;br /&gt;
            $( NavToggle ).on( &#039;click&#039;, $.proxy( window.toggleNavigationBar, window, indexNavigationBar ) );&lt;br /&gt;
 &lt;br /&gt;
            var isCollapsed = $( NavFrame ).hasClass( &#039;collapsed&#039; );&lt;br /&gt;
            /**&lt;br /&gt;
             * Check if any children are already hidden.  This loop is here for backwards compatibility:&lt;br /&gt;
             * the old way of making NavFrames start out collapsed was to manually add style=&amp;quot;display:none&amp;quot;&lt;br /&gt;
             * to all the NavPic/NavContent elements.  Since this was bad for accessibility (no way to make&lt;br /&gt;
             * the content visible without JavaScript support), the new recommended way is to add the class&lt;br /&gt;
             * &amp;quot;collapsed&amp;quot; to the NavFrame itself, just like with collapsible tables.&lt;br /&gt;
             */&lt;br /&gt;
            for ( NavChild = NavFrame.firstChild; NavChild != null &amp;amp;&amp;amp; !isCollapsed; NavChild = NavChild.nextSibling ) {&lt;br /&gt;
                if ( $( NavChild ).hasClass( &#039;NavPic&#039; ) || $( NavChild ).hasClass( &#039;NavContent&#039; ) ) {&lt;br /&gt;
                    if ( NavChild.style.display === &#039;none&#039; ) {&lt;br /&gt;
                        isCollapsed = true;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            if ( isCollapsed ) {&lt;br /&gt;
                for ( NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling ) {&lt;br /&gt;
                    if ( $( NavChild ).hasClass( &#039;NavPic&#039; ) || $( NavChild ).hasClass( &#039;NavContent&#039; ) ) {&lt;br /&gt;
                        NavChild.style.display = &#039;none&#039;;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            var NavToggleText = document.createTextNode( isCollapsed ? NavigationBarShow : NavigationBarHide );&lt;br /&gt;
            NavToggle.appendChild( NavToggleText );&lt;br /&gt;
 &lt;br /&gt;
            /* Find the NavHead and attach the toggle link (Must be this complicated because Moz&#039;s firstChild handling is borked) */&lt;br /&gt;
            for( var j = 0; j &amp;lt; NavFrame.childNodes.length; j++ ) {&lt;br /&gt;
                if ( $( NavFrame.childNodes[j] ).hasClass( &#039;NavHead&#039; ) ) {&lt;br /&gt;
                    NavToggle.style.color = NavFrame.childNodes[j].style.color;&lt;br /&gt;
                    NavFrame.childNodes[j].appendChild( NavToggle );&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            NavFrame.setAttribute( &#039;id&#039;, &#039;NavFrame&#039; + indexNavigationBar );&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
$( createNavigationBarToggleButton );&lt;br /&gt;
 &lt;br /&gt;
/**&lt;br /&gt;
 * Uploadwizard_newusers&lt;br /&gt;
 * Switches in a message for non-autoconfirmed users at [[Wikipedia:Upload]]&lt;br /&gt;
 *&lt;br /&gt;
 * Maintainers: [[User:Krimpet]]&lt;br /&gt;
 */&lt;br /&gt;
function uploadwizard_newusers() {&lt;br /&gt;
    if ( mw.config.get( &#039;wgNamespaceNumber&#039; ) === 4 &amp;amp;&amp;amp; mw.config.get( &#039;wgTitle&#039; ) === &#039;Upload&#039; &amp;amp;&amp;amp; mw.config.get( &#039;wgAction&#039; ) === &#039;view&#039; ) {&lt;br /&gt;
        var oldDiv = document.getElementById( &#039;autoconfirmedusers&#039; ),&lt;br /&gt;
            newDiv = document.getElementById( &#039;newusers&#039; );&lt;br /&gt;
        if ( oldDiv &amp;amp;&amp;amp; newDiv ) {&lt;br /&gt;
            var userGroups = mw.config.get( &#039;wgUserGroups&#039; );&lt;br /&gt;
            if ( userGroups ) {&lt;br /&gt;
                for ( var i = 0; i &amp;lt; userGroups.length; i++ ) {&lt;br /&gt;
                    if ( userGroups[i] === &#039;autoconfirmed&#039; ) {&lt;br /&gt;
                        oldDiv.style.display = &#039;block&#039;;&lt;br /&gt;
                        newDiv.style.display = &#039;none&#039;;&lt;br /&gt;
                        return;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            oldDiv.style.display = &#039;none&#039;;&lt;br /&gt;
            newDiv.style.display = &#039;block&#039;;&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
$(uploadwizard_newusers);&lt;br /&gt;
 &lt;br /&gt;
/**&lt;br /&gt;
 * Magic editintros ****************************************************&lt;br /&gt;
 *&lt;br /&gt;
 * Description: Adds editintros on disambiguation pages and BLP pages.&lt;br /&gt;
 * Maintainers: [[User:RockMFR]]&lt;br /&gt;
 */&lt;br /&gt;
function addEditIntro( name ) {&lt;br /&gt;
    $( &#039;.editsection, #ca-edit&#039; ).find( &#039;a&#039; ).each( function ( i, el ) {&lt;br /&gt;
        el.href = $( this ).attr( &#039;href&#039; ) + &#039;&amp;amp;editintro=&#039; + name;&lt;br /&gt;
    } );&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
if ( mw.config.get( &#039;wgNamespaceNumber&#039; ) === 0 ) {&lt;br /&gt;
    $( function () {&lt;br /&gt;
        if ( document.getElementById( &#039;disambigbox&#039; ) ) {&lt;br /&gt;
            addEditIntro( &#039;Template:Disambig_editintro&#039; );&lt;br /&gt;
        }&lt;br /&gt;
    } );&lt;br /&gt;
 &lt;br /&gt;
    $( function () {&lt;br /&gt;
        var cats = document.getElementById( &#039;mw-normal-catlinks&#039; );&lt;br /&gt;
        if ( !cats ) {&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        cats = cats.getElementsByTagName( &#039;a&#039; );&lt;br /&gt;
        for ( var i = 0; i &amp;lt; cats.length; i++ ) {&lt;br /&gt;
            if ( cats[i].title === &#039;Category:Living people&#039; || cats[i].title === &#039;Category:Possibly living people&#039; ) {&lt;br /&gt;
                addEditIntro( &#039;Template:BLP_editintro&#039; );&lt;br /&gt;
                break;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    } );&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
/**&lt;br /&gt;
 * Description: Stay on the secure server as much as possible&lt;br /&gt;
 * Maintainers: [[User:TheDJ]]&lt;br /&gt;
 */&lt;br /&gt;
if ( document.location &amp;amp;&amp;amp; document.location.protocol  &amp;amp;&amp;amp; document.location.protocol === &#039;https:&#039; ) {&lt;br /&gt;
    /* New secure servers */&lt;br /&gt;
    importScript( &#039;MediaWiki:Common.js/secure new.js&#039; );&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
/* End of mw.loader.using callback */&lt;br /&gt;
} );&lt;br /&gt;
/* DO NOT ADD CODE BELOW THIS LINE */&lt;br /&gt;
&lt;br /&gt;
/* AJLSM - Boutons personnalises de WikiEditor */&lt;br /&gt;
mw.loader.load( mw.util.getUrl( &#039;MediaWiki:AJLSM-WikiEditor.js&#039;, {&lt;br /&gt;
    action: &#039;raw&#039;,&lt;br /&gt;
    ctype: &#039;text/javascript&#039;&lt;br /&gt;
} ) );&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=MediaWiki:AJLSM-WikiEditor.js&amp;diff=6528</id>
		<title>MediaWiki:AJLSM-WikiEditor.js</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=MediaWiki:AJLSM-WikiEditor.js&amp;diff=6528"/>
		<updated>2026-11-06T12:23:29Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : Restauration des boutons WikiEditor AJLSM - premier test&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
mw.hook( &#039;wikiEditor.toolbarReady&#039; ).add( function ( $textarea ) {&lt;br /&gt;
    $textarea.wikiEditor( &#039;addToToolbar&#039;, {&lt;br /&gt;
        section: &#039;advanced&#039;,&lt;br /&gt;
        group: &#039;insert&#039;,&lt;br /&gt;
        tools: {&lt;br /&gt;
            ajlsmPath: {&lt;br /&gt;
                label: &#039;Ajouter un chemin vers un fichier/dossier&#039;,&lt;br /&gt;
                type: &#039;button&#039;,&lt;br /&gt;
                icon: mw.config.get( &#039;wgScriptPath&#039; ) + &#039;/images/9/96/Toolbar-path.svg&#039;,&lt;br /&gt;
                action: {&lt;br /&gt;
                    type: &#039;encapsulate&#039;,&lt;br /&gt;
                    options: {&lt;br /&gt;
                        pre: &#039;{{path|&#039;,&lt;br /&gt;
                        peri: &#039;/path/to/dir-or-file&#039;,&lt;br /&gt;
                        post: &#039;}}&#039;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    } );&lt;br /&gt;
} );&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=WAF_2026&amp;diff=6525</id>
		<title>WAF 2026</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=WAF_2026&amp;diff=6525"/>
		<updated>2026-11-05T14:32:40Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : /* Certificats automatiques (SSL Lets Encrypt) via Haproxy */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:Ansile]][[category:Haproxy]][[category:modsec]][[category:coraza]]&lt;br /&gt;
== Documentation externe ==&lt;br /&gt;
Voir Coraza : https://www.coraza.io/&lt;br /&gt;
[[category:letsencrypt]][[category:OPNsense]][[category:opnsens]][[category:opensens]][[category:opensense]]&lt;br /&gt;
WAF : Web Application Firewall.&lt;br /&gt;
&lt;br /&gt;
== Description de l&#039;infrastructure ==&lt;br /&gt;
=== Schéma de l&#039;infra ===&lt;br /&gt;
&lt;br /&gt;
Dans notre infra (aujourd&#039;hui Saturne3) et sur Proxmox, on a installé 4 VM. &lt;br /&gt;
&lt;br /&gt;
2 VM Haproxy (en cluster) récupèrent le flux et le renvoi vers 2 VM modsecurity (en cluster) qui analysent et traitent les requêtes et renvoient vers les VM HAPROXY qui renvoient, ou non, vers les VM clients.&lt;br /&gt;
&lt;br /&gt;
* Mise en place de deux nœuds Haproxy redondés via VRRP &lt;br /&gt;
# IP 1 : 10.0.0.30, &lt;br /&gt;
# IP 2 : 10.0.0.31, &lt;br /&gt;
# IP redondée/balancée : 10.0.0.32, IP externe redondée : 51.83.117.120)&lt;br /&gt;
{{important|Pré-requis pour les étapes suivantes :&lt;br /&gt;
# Accès par VPN Wireguard, ou,&lt;br /&gt;
# Accès par OpenVPN,&lt;br /&gt;
# Utilisateur root}}&lt;br /&gt;
&lt;br /&gt;
== Ajouts des certificats SSL (manuelle) ==&lt;br /&gt;
=== Rajouter un domaine (un certificat SSL) dans le reverse proxy HAPROXY ===&lt;br /&gt;
1 -&amp;gt; Copier le certificat complet (voir où se trouve les certificats dans la conf apache du domaine ...-le-ssl.conf, puis réunir la clé publique et la clé privée en 1 fichier. &lt;br /&gt;
&lt;br /&gt;
Depuis la VM (voir celui de portdunkerque pour exemple) vers les 2 VM HAPROXY,&lt;br /&gt;
dans {{path|/etc/haproxy/certs/}} en prenant soin de respecter le nom de domaine, par exemple :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;port-dunkerque.pleade.com.pem&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Une fois les certificats SSL en place, relancez le service haproxy :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;service haproxy reload&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{notice|Contrairement à la recommandation qui suit, l&#039;intégration du contenu des fichiers .crt, .key et .pem fonctionne très bien : Attention, ne pas ajouter le contenu du fichier .pem s&#039;il existe !}}&lt;br /&gt;
&lt;br /&gt;
==Certificats automatiques (SSL Lets Encrypt) via Haproxy==&lt;br /&gt;
{{important|Utiliser le projet Ansible : [[WAF#Ansible]]}}&lt;br /&gt;
{{important|Le domaine doit être géré par Haproxy. Il doit être &amp;quot;derrière&amp;quot; le pare-feu, c&#039;est-à-dire : Firewall: NAT: One-to-One : IP interne 10.0.0.32. Ne fonctionne pas avec l&#039;IP native du serveur.}}&lt;br /&gt;
===Modification du fichier haproxy.yml d&#039;Ansible===&lt;br /&gt;
# Le chemin des certificats change de /etc/haproxy/ssl à /etc/haproxy/certs&lt;br /&gt;
# Ajout de la clé ACCOUNT_THUMBPRINT qui gère les challenge acme-challenge&lt;br /&gt;
===Ajout de certificat sur un nouveau domaine===&lt;br /&gt;
L&#039;exemple ici porte sur port-dunkerque.pleade.com&lt;br /&gt;
{{important|A exécuter séquentiellement (un après l&#039;autre, pas en parallèle) sur HAPROXY-01 et HAPROXY-02}}&lt;br /&gt;
====S&#039;authentifier en tant qu&#039;acme====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;$ sudo -u acme -s                       /!\ IMPORTANT d&#039;être authentifié en tant qu&#039;acme&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
====Génération des certificats via LetsEncrypt====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;$ acme.sh --issue -d port-dunkerque.pleade.com --stateless --server letsencrypt&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
====Déploiement dans le dossier Haproxy grâce au hook correspondant qui met à jour à chaud les certs====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;$ DEPLOY_HAPROXY_HOT_UPDATE=yes DEPLOY_HAPROXY_STATS_SOCKET=/var/run/haproxy/admin.sock DEPLOY_HAPROXY_PEM_PATH=/etc/haproxy/certs  acme.sh --deploy -d port-dunkerque.pleade.com --deploy-hook haproxy&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{notice|Si, en tant qu&#039;acme, on fait un crontab -l, on peut voir qu&#039;une tâche de renouvellement de certificats tourne régulièrement.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Certificats automatiques Let&#039;s Encrypt via HAProxy =&lt;br /&gt;
&lt;br /&gt;
== Présentation ==&lt;br /&gt;
&lt;br /&gt;
Les certificats TLS des domaines publiés par les serveurs HAProxy AJLSM sont gérés avec &#039;&#039;&#039;acme.sh&#039;&#039;&#039; et &#039;&#039;&#039;Let&#039;s Encrypt&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
L&#039;installation et le renouvellement des certificats sont effectués sur deux serveurs :&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;haproxy-01&#039;&#039;&#039; : 10.0.0.30&lt;br /&gt;
* &#039;&#039;&#039;haproxy-02&#039;&#039;&#039; : 10.0.0.31&lt;br /&gt;
&lt;br /&gt;
Les certificats sont stockés dans :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/etc/haproxy/certs/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le hook &#039;&#039;haproxy&#039;&#039; d&#039;acme.sh permet le déploiement des certificats et leur mise à jour à chaud par le socket d&#039;administration HAProxy.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Les opérations doivent être effectuées &#039;&#039;&#039;successivement sur HAProxy-01 puis HAProxy-02&#039;&#039;&#039;, jamais en parallèle.&lt;br /&gt;
&lt;br /&gt;
Chaque serveur possède sa propre installation d&#039;acme.sh et ses propres certificats. Il n&#039;existe pas de synchronisation automatique des fichiers PEM entre les deux serveurs.&lt;br /&gt;
&lt;br /&gt;
== 1. Prérequis ==&lt;br /&gt;
&lt;br /&gt;
=== 1.1. Configuration réseau et DNS ===&lt;br /&gt;
&lt;br /&gt;
Le domaine doit :&lt;br /&gt;
&lt;br /&gt;
* disposer d&#039;un enregistrement DNS public pointant vers l&#039;adresse IP publique utilisée par l&#039;infrastructure ;&lt;br /&gt;
* être acheminé par OPNsense vers la VIP HAProxy &#039;&#039;&#039;10.0.0.32&#039;&#039;&#039; ;&lt;br /&gt;
* être pris en charge par la configuration HAProxy.&lt;br /&gt;
&lt;br /&gt;
La configuration NAT dépend de l&#039;adresse publique concernée.&lt;br /&gt;
&lt;br /&gt;
Pour l&#039;installation de CDF du 5 novembre 2026, le routage utilise &#039;&#039;&#039;OPNsense Destination NAT&#039;&#039;&#039;, et non NAT One-to-One.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Le domaine doit être publié derrière HAProxy. La procédure de validation ACME ne fonctionne pas si les requêtes arrivent directement sur un serveur qui ne dispose pas de la configuration de validation correspondante.&lt;br /&gt;
&lt;br /&gt;
La validation Let&#039;s Encrypt utilise le challenge HTTP-01 en mode &#039;&#039;&#039;stateless&#039;&#039;&#039;, sur le port 80.&lt;br /&gt;
&lt;br /&gt;
=== 1.2. Configuration HAProxy avec Ansible ===&lt;br /&gt;
&lt;br /&gt;
La configuration HAProxy est maintenue dans le projet Ansible AJLSM.&lt;br /&gt;
&lt;br /&gt;
Voir : [[WAF#Ansible]]&lt;br /&gt;
&lt;br /&gt;
Les éléments nécessaires comprennent :&lt;br /&gt;
&lt;br /&gt;
* le répertoire des certificats &amp;lt;code&amp;gt;/etc/haproxy/certs/&amp;lt;/code&amp;gt; ;&lt;br /&gt;
* la clé &amp;lt;code&amp;gt;ACCOUNT_THUMBPRINT&amp;lt;/code&amp;gt; utilisée pour la validation ACME ;&lt;br /&gt;
* la règle HTTP permettant de répondre aux requêtes &amp;lt;code&amp;gt;/.well-known/acme-challenge/&amp;lt;/code&amp;gt; ;&lt;br /&gt;
* les ACL correspondant au domaine ;&lt;br /&gt;
* le backend associé à l&#039;application.&lt;br /&gt;
&lt;br /&gt;
La configuration Ansible doit être déployée et validée avant de demander le certificat.&lt;br /&gt;
&lt;br /&gt;
== 2. Création d&#039;un certificat ==&lt;br /&gt;
&lt;br /&gt;
L&#039;exemple suivant concerne le domaine :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
cdf-recette.pleade.com&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Toutes les opérations doivent être réalisées sur HAProxy-01, puis répétées sur HAProxy-02.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== 2.1. S&#039;authentifier en tant qu&#039;acme ===&lt;br /&gt;
&lt;br /&gt;
Depuis une session administrateur :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo -u acme -s&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Les commandes acme.sh doivent être exécutées avec l&#039;utilisateur &#039;&#039;&#039;acme&#039;&#039;&#039;, et non avec root.&lt;br /&gt;
&lt;br /&gt;
=== 2.2. Générer le certificat avec Let&#039;s Encrypt ===&lt;br /&gt;
&lt;br /&gt;
Toujours dans la session de l&#039;utilisateur &amp;lt;code&amp;gt;acme&amp;lt;/code&amp;gt; :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
acme.sh --issue \&lt;br /&gt;
  -d cdf-recette.pleade.com \&lt;br /&gt;
  --stateless \&lt;br /&gt;
  --server letsencrypt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier que la commande se termine par :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Success&lt;br /&gt;
Cert success.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les fichiers générés sont enregistrés dans :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/var/lib/acme/.acme.sh/cdf-recette.pleade.com_ecc/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce répertoire contient notamment :&lt;br /&gt;
&lt;br /&gt;
* le certificat ;&lt;br /&gt;
* la clé privée ;&lt;br /&gt;
* le certificat intermédiaire ;&lt;br /&gt;
* la chaîne complète.&lt;br /&gt;
&lt;br /&gt;
Ne pas modifier manuellement ces fichiers.&lt;br /&gt;
&lt;br /&gt;
=== 2.3. Déployer le certificat dans HAProxy ===&lt;br /&gt;
&lt;br /&gt;
Toujours avec l&#039;utilisateur &amp;lt;code&amp;gt;acme&amp;lt;/code&amp;gt; :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
DEPLOY_HAPROXY_HOT_UPDATE=yes \&lt;br /&gt;
DEPLOY_HAPROXY_STATS_SOCKET=/var/run/haproxy/admin.sock \&lt;br /&gt;
DEPLOY_HAPROXY_PEM_PATH=/etc/haproxy/certs \&lt;br /&gt;
acme.sh --deploy \&lt;br /&gt;
  -d cdf-recette.pleade.com \&lt;br /&gt;
  --deploy-hook haproxy&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette commande :&lt;br /&gt;
&lt;br /&gt;
# prépare le certificat au format PEM ;&lt;br /&gt;
# l&#039;installe dans &amp;lt;code&amp;gt;/etc/haproxy/certs/&amp;lt;/code&amp;gt; ;&lt;br /&gt;
# demande son chargement à chaud par HAProxy via le socket d&#039;administration.&lt;br /&gt;
&lt;br /&gt;
Lors de l&#039;installation CDF du 5 novembre 2026, le résultat a été :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Deploying PEM file&lt;br /&gt;
Moving new certificate into place&lt;br /&gt;
Creating new certificate &#039;/etc/haproxy/certs/cdf-recette.pleade.com.pem&#039; over HAProxy stats socket.&lt;br /&gt;
Success&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le certificat a donc été émis et son déploiement a réussi.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
La réussite du déploiement ne dispense pas de vérifier que HAProxy présente effectivement le nouveau certificat lors d&#039;une connexion HTTPS.&lt;br /&gt;
&lt;br /&gt;
== 3. Vérifications après installation ==&lt;br /&gt;
&lt;br /&gt;
=== 3.1. Vérifier la présence du fichier PEM ===&lt;br /&gt;
&lt;br /&gt;
Depuis une session administrateur :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ls -l /etc/haproxy/certs/cdf-recette.pleade.com.pem&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le fichier doit être présent dans le répertoire des certificats HAProxy.&lt;br /&gt;
&lt;br /&gt;
=== 3.2. Vérifier le certificat et ses dates ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
openssl x509 \&lt;br /&gt;
  -in /etc/haproxy/certs/cdf-recette.pleade.com.pem \&lt;br /&gt;
  -noout -subject -dates&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier :&lt;br /&gt;
&lt;br /&gt;
* le nom du domaine ;&lt;br /&gt;
* la date de début de validité ;&lt;br /&gt;
* la date d&#039;expiration.&lt;br /&gt;
&lt;br /&gt;
=== 3.3. Tester l&#039;accès HTTPS ===&lt;br /&gt;
&lt;br /&gt;
Depuis un poste extérieur :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -vI --max-time 10 \&lt;br /&gt;
  --resolve cdf-recette.pleade.com:443:51.83.117.113 \&lt;br /&gt;
  https://cdf-recette.pleade.com/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;option &amp;lt;code&amp;gt;--resolve&amp;lt;/code&amp;gt; permet de forcer l&#039;adresse IP publique et de contourner un éventuel cache DNS obsolète.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ne pas utiliser l&#039;option -k pour le contrôle final.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Il faut vérifier que :&lt;br /&gt;
&lt;br /&gt;
* la négociation TLS aboutit ;&lt;br /&gt;
* le certificat est reconnu comme valide ;&lt;br /&gt;
* le certificat correspond au domaine demandé ;&lt;br /&gt;
* le serveur répond avec un code HTTP attendu (200 ou redirection légitime).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Lorsque deux HAProxy partagent une VIP, un test par l&#039;adresse IP publique ne permet pas nécessairement de savoir quel serveur a répondu.&lt;br /&gt;
&lt;br /&gt;
Les deux nœuds doivent donc être contrôlés individuellement.&lt;br /&gt;
&lt;br /&gt;
== 4. Répéter l&#039;installation sur HAProxy-02 ==&lt;br /&gt;
&lt;br /&gt;
Après validation de HAProxy-01 :&lt;br /&gt;
&lt;br /&gt;
# se connecter à HAProxy-02 ;&lt;br /&gt;
# ouvrir une session sous l&#039;utilisateur &amp;lt;code&amp;gt;acme&amp;lt;/code&amp;gt; ;&lt;br /&gt;
# exécuter la commande &amp;lt;code&amp;gt;acme.sh --issue&amp;lt;/code&amp;gt; ;&lt;br /&gt;
# exécuter la commande &amp;lt;code&amp;gt;acme.sh --deploy&amp;lt;/code&amp;gt; ;&lt;br /&gt;
# vérifier la présence du fichier PEM ;&lt;br /&gt;
# vérifier le certificat ;&lt;br /&gt;
# contrôler son chargement effectif par HAProxy.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ne jamais considérer l&#039;installation comme terminée tant que le certificat n&#039;a pas été installé et vérifié sur les deux serveurs.&lt;br /&gt;
&lt;br /&gt;
== 5. Renouvellement automatique ==&lt;br /&gt;
&lt;br /&gt;
Une tâche cron de l&#039;utilisateur &amp;lt;code&amp;gt;acme&amp;lt;/code&amp;gt; exécute régulièrement acme.sh afin de renouveler les certificats arrivant à expiration.&lt;br /&gt;
&lt;br /&gt;
=== 5.1. Vérifier la tâche cron ===&lt;br /&gt;
&lt;br /&gt;
Depuis une session administrateur :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo crontab -u acme -l&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sur HAProxy-01, la tâche observée le 5 novembre 2026 est :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
27 19 * * * /usr/local/share/acme.sh/acme.sh --cron --home &amp;quot;/var/lib/acme/.acme.sh&amp;quot; &amp;gt; /dev/null&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5.2. Lister les certificats gérés ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo -u acme /usr/local/bin/acme.sh \&lt;br /&gt;
  --list \&lt;br /&gt;
  --home /var/lib/acme/.acme.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier que le nouveau domaine apparaît dans la liste.&lt;br /&gt;
&lt;br /&gt;
=== 5.3. Paramètres du hook HAProxy ===&lt;br /&gt;
&lt;br /&gt;
Les paramètres de déploiement sont enregistrés dans la configuration propre au domaine.&lt;br /&gt;
&lt;br /&gt;
Exemple pour Mercure3 :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Le_DeployHook=&#039;haproxy,&#039;&lt;br /&gt;
Le_Deploy_haproxy_pem_path=&#039;/etc/haproxy/certs&#039;&lt;br /&gt;
Le_Deploy_haproxy_hot_update=&#039;yes&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ces paramètres permettent à acme.sh de retrouver le mécanisme de déploiement lors des renouvellements.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
La présence du hook dans la configuration ne garantit pas à elle seule que le renouvellement et le chargement à chaud aboutiront.&lt;br /&gt;
&lt;br /&gt;
Le renouvellement doit être contrôlé sur les deux HAProxy.&lt;br /&gt;
&lt;br /&gt;
== 6. Points d&#039;attention ==&lt;br /&gt;
&lt;br /&gt;
* Toujours intervenir successivement sur HAProxy-01 puis HAProxy-02.&lt;br /&gt;
* Toujours exécuter acme.sh avec l&#039;utilisateur &amp;lt;code&amp;gt;acme&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Ne pas modifier directement les certificats gérés par acme.sh.&lt;br /&gt;
* Ne pas confondre émission, déploiement et activation effective du certificat.&lt;br /&gt;
* Vérifier le DNS public avant l&#039;émission.&lt;br /&gt;
* Vérifier le fonctionnement du challenge HTTP-01 sur le port 80.&lt;br /&gt;
* Ne pas modifier le mécanisme de renouvellement existant sans validation.&lt;br /&gt;
* Contrôler la validité du certificat sur les deux HAProxy.&lt;br /&gt;
* Ne pas supposer qu&#039;un certificat installé sur HAProxy-01 est automatiquement disponible sur HAProxy-02.&lt;br /&gt;
&lt;br /&gt;
== 7. Historique des installations ==&lt;br /&gt;
&lt;br /&gt;
=== 5 novembre 2026 — cdf-recette.pleade.com ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Élément&lt;br /&gt;
! Valeur ou état&lt;br /&gt;
|-&lt;br /&gt;
| Domaine&lt;br /&gt;
| &amp;lt;code&amp;gt;cdf-recette.pleade.com&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| IP publique&lt;br /&gt;
| &amp;lt;code&amp;gt;51.83.117.113&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| VIP HAProxy&lt;br /&gt;
| &amp;lt;code&amp;gt;10.0.0.32&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| VM applicative&lt;br /&gt;
| &amp;lt;code&amp;gt;mercure3 — 10.0.0.43&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Backend HAProxy&lt;br /&gt;
| &amp;lt;code&amp;gt;back_mercure3&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Port backend&lt;br /&gt;
| &amp;lt;code&amp;gt;80&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Émission Let&#039;s Encrypt sur HAProxy-01&lt;br /&gt;
| Réussie&lt;br /&gt;
|-&lt;br /&gt;
| Déploiement à chaud sur HAProxy-01&lt;br /&gt;
| Réussi&lt;br /&gt;
|-&lt;br /&gt;
| Contrôle HTTPS&lt;br /&gt;
| À effectuer&lt;br /&gt;
|-&lt;br /&gt;
| Installation sur HAProxy-02&lt;br /&gt;
| À effectuer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
La procédure sera considérée comme entièrement validée après les contrôles HTTPS sur les deux serveurs.&lt;br /&gt;
&lt;br /&gt;
== Configuration de HaProxy - Méthode 1 ==&lt;br /&gt;
On utilise ansible pour générer les fichiers de configuration dans Haproxy, les appliquer, redémarrer les Haproxy, etc. &lt;br /&gt;
&lt;br /&gt;
[[WAF#Ansible|Voir la section : Ansible]]&lt;br /&gt;
&lt;br /&gt;
La configuration du fichier est la même, avec la possibilité de &lt;br /&gt;
# variabiliser : voir section : http://mw.ajlsm.com/wiki/WAF#Variabilisation&lt;br /&gt;
# déployer la configuration sur les 2 Haproxy en une seule action.&lt;br /&gt;
&lt;br /&gt;
Pour utiliser cette méthode, récupérer le projet &#039;&#039;&#039;ansible-ajlsm-haproxy&#039;&#039;&#039; en SVN.&lt;br /&gt;
&lt;br /&gt;
La création des règles est la même que celle décrite en méthode 2.&lt;br /&gt;
&lt;br /&gt;
La différence est que l&#039;on ne travaille pas &amp;quot;directement&amp;quot; dans le fichier {{path|/etc/haproxy/haproxy.cfg}}, mais dans le fichier {{path|/ansible-ajlsm-haproxy/inventory/group_vars/ajlsm_loadbalancer/haproxy.yml}} qui est déployé en ligne de commande avec Ansible. &lt;br /&gt;
&lt;br /&gt;
Cette méthode est celle utilisée en production.&lt;br /&gt;
&lt;br /&gt;
== Configuration de HaProxy - Méthode 2 ==&lt;br /&gt;
Voir aussi projet ansible en SVN : [[WAF#Ansible]].&lt;br /&gt;
 &lt;br /&gt;
Modifier directement le fichier de configuration configuration {{path|/etc/haproxy/haproxy.cfg}}.&lt;br /&gt;
&lt;br /&gt;
Rajouter les lignes suivantes dans la configuration {{path|/etc/haproxy/haproxy.cfg}} (dans les blocs {{path|frontend front_web}} et {{path|backend }}) :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
acl host_leclientvoulu hdr(host) -i lenomdedomaineduclientvoulu.com&lt;br /&gt;
use_backend back_leclientvoulu if host_leclientvoulu&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
et rajouter un nouveau bloc backend comme ceci :&lt;br /&gt;
# Configuration avec certificat SSL :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;backend back_leclientvoulu&lt;br /&gt;
   server LECLIENTVOULU ipduclientvoulu:443 check ssl verify none&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# Configuration sans certificat :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;backend back_leclientvoulu&lt;br /&gt;
   server LECLIENTVOULU ipduclientvoulu:80 check&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Par exemple, pour archives.lamayenne.fr :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;        acl host_ssl_archiveslamayenne  hdr(host)               -i          archives.lamayenne.fr&lt;br /&gt;
        use_backend back_ssl_archiveslamayenne                  if          host_ssl_archiveslamayenne&lt;br /&gt;
&lt;br /&gt;
        acl host_salledelecturearchiveslamayenne  hdr(host)       -i      salle-de-lecture-archives.lamayenne.fr&lt;br /&gt;
        use_backend back_salledelecturearchiveslamayenne          if      host_salledelecturearchiveslamayenne&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
backend back_ssl_archiveslamayenne&lt;br /&gt;
        server ARCHIVESLAMAYENNE                ad53.ajlsm.lan:443 check ssl verify none&lt;br /&gt;
&lt;br /&gt;
backend back_salledelecturearchiveslamayenne&lt;br /&gt;
        server SALLEDELECTUREARCHIVESLAMAYENNE  ad53.ajlsm.lan:80 check&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Traitement des blocages par IP ===&lt;br /&gt;
La règle apache pour le blocage des IP de chaque site : &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;RewriteCond %{REMOTE_ADDR}&amp;lt;/syntaxhighlight&amp;gt; renvoie sur le Haproxy. &lt;br /&gt;
&lt;br /&gt;
Le blocage d&#039;IP ne se fait plus. &lt;br /&gt;
&lt;br /&gt;
Lorsque toutes les IP doivent être bloquées sauf les accès prévus : pour le client, AJLSM, etc, (Par exemple, pour une application intranet) la &#039;&#039;&#039;gestion des accès par IP est à configurer dans Haproxy&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
De plus, les [[WAF#Modification_de_la_configuration_apache_des_domaines|configurations apache]] doivent être modifiées sur chaque VM.&lt;br /&gt;
==== Blocage des IP dans Haproxy ====&lt;br /&gt;
Créez les IP allowed dans la configuration Haproxy en ajoutant, dans le {{var|frontend front_web}} et avant les autres acl, l&#039;instruction suivante :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;        acl allowed_ajlsm src xx.xx.xx.xx xx.xx.xx.xx xx.xx.xx.xx/xx&lt;br /&gt;
        acl allowed_xx_client src xx.xx.xx.xx&lt;br /&gt;
&lt;br /&gt;
(Par exemple, pour les IP AJLSM et le client ad53)&lt;br /&gt;
&lt;br /&gt;
        acl allowed_ajlsm src 82.65.94.250 109.190.129.96 91.174.149.42 10.0.0.0/24&lt;br /&gt;
        acl allowed_ad53_client src 85.115.60.201&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==== Association des règles aux acl du client ====&lt;br /&gt;
Enfin, modifier les acl des domaines qui utilisent ces règles de blocage d&#039;IP en ajoutant l&#039;instruction suivante :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;        http-request deny                                         if      host_[le-host] !allowed_ajlsm !allowed_xx_client&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Par exemple :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;        acl host_salledelecturearchiveslamayenne  hdr(host)       -i      salle-de-lecture-archives.lamayenne.fr&lt;br /&gt;
        use_backend back_salledelecturearchiveslamayenne          if      host_salledelecturearchiveslamayenne&lt;br /&gt;
        http-request deny                                         if      host_salledelecturearchiveslamayenne !allowed_ajlsm !allowed_ad53_client&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==== Forcer le HTTPS sur un domaine ====&lt;br /&gt;
On souhaite que le WAF prenne bien en compte l&#039;acl pour un domaine avec SSL.&lt;br /&gt;
&lt;br /&gt;
Ajouter la commande suivante dans l&#039;acl concerné.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;http-request redirect scheme https                      if          { hdr(Host) -i [le-domaine] } !{ ssl_fc }&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Par exemple, pour ad53 :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;        acl host_ssl_archiveslamayenne  hdr(host)               -i          archives.lamayenne.fr&lt;br /&gt;
        use_backend back_ssl_archiveslamayenne                  if          host_ssl_archiveslamayenne&lt;br /&gt;
        http-request redirect scheme https                      if          { hdr(Host) -i archives.lamayenne.fr } !{ ssl_fc }&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Vérifier la configuration haproxy avec la commande : &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;haproxy -f /etc/haproxy/haproxy.cfg -c -V&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modification de la configuration apache des domaines ==&lt;br /&gt;
Dans la configuration apache de chaque site, il faut ajouter les IP privées des 2 Haproxy.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;        RewriteCond %{REMOTE_ADDR} !10.0.0.30&lt;br /&gt;
        RewriteCond %{REMOTE_ADDR} !10.0.0.31&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Puis, commenter la ligne :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;#RewriteRule .* /403.html [R=403,L]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Modification des logs pour le suivi des utilisateurs ====&lt;br /&gt;
Lorsque l&#039;on bascule le flux vers le WAF, c&#039;est l&#039;IP de Haproxy qui est la seule à communiquer avec la VM.&lt;br /&gt;
&lt;br /&gt;
Pour avoir des statistiques du nombre d&#039;utilisateurs, il faut modifier les configuration apache et ajoutant les instructions suivantes (conserver la configuration hors WAF en cas de suppression du WAF) :&lt;br /&gt;
&lt;br /&gt;
Activer le module Apache remoteip :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;a2enmod remoteip&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Modifier la configuration Apache du site :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;       # Configuration des logs pour suivi par IP utilisateurs&lt;br /&gt;
        RemoteIPHeader X-Forwarded-For&lt;br /&gt;
        LogFormat &amp;quot;%a %l %u %t \&amp;quot;%r\&amp;quot; %&amp;gt;s %b \&amp;quot;%{Referer}i\&amp;quot; \&amp;quot;%{User-Agent}i\&amp;quot;&amp;quot; forwarded&lt;br /&gt;
&lt;br /&gt;
        ErrorLog /var/log/apache2/archives.lamayenne.fr.errors.log&lt;br /&gt;
        CustomLog /var/log/apache2/archives.lamayenne.fr.log forwarded&lt;br /&gt;
        # Fin configuration des logs pour suivi par IP utilisateurs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        #### Configuration log hors WAF &lt;br /&gt;
        #ErrorLog /var/log/apache2/archives.lamayenne.fr.errors.log&lt;br /&gt;
        #CustomLog /var/log/apache2/archives.lamayenne.fr.log combined&lt;br /&gt;
        #### Fin configuration log hors WAF&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Application des règles HaProxy ==&lt;br /&gt;
Une fois les modifications terminées, on applique la configuration en relançant le service.&lt;br /&gt;
=== Redémarrer HAPROXY ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;service haproxy restart&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Vérifier que le HAPROXY est en vie ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;service haproxy status&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Logrotate Haproxy ===&lt;br /&gt;
Le logrotate est configuré et fait une rotation journalière (configuration dans {{path|/etc/logrotate.d/haproxy}}),&lt;br /&gt;
Il y a un palier maximum de 500M par fichier de log (on peut adapter). &lt;br /&gt;
&lt;br /&gt;
Le log est compressé (en .1, .2.gz ...) soit lorsqu&#039;il atteint 500M, soit au terme de la journée.&lt;br /&gt;
Les plus anciens logs compressés sont supprimés graduellement et automatiquement.&lt;br /&gt;
&lt;br /&gt;
La conf est la suivante :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;/var/log/haproxy.log {&lt;br /&gt;
   daily&lt;br /&gt;
   rotate 15&lt;br /&gt;
   maxsize 500M&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Problèmes et solutions ==&lt;br /&gt;
En cas d&#039;erreur de configuration, on peut sortir un état plus détaillé du service haproxy avec la commande :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;$ sudo systemctl status haproxy.service -l --no-pager&lt;br /&gt;
● haproxy.service - HAProxy Load Balancer&lt;br /&gt;
     Loaded: loaded (/lib/systemd/system/haproxy.service; enabled; vendor preset: enabled)&lt;br /&gt;
     Active: active (running) since Thu 2022-05-19 10:36:36 UTC; 9s ago&lt;br /&gt;
       Docs: man:haproxy(1)&lt;br /&gt;
             file:/usr/share/doc/haproxy/configuration.txt.gz&lt;br /&gt;
    Process: 88895 ExecStartPre=/usr/sbin/haproxy -f $CONFIG -c -q $EXTRAOPTS (code=exited, status=0/SUCCESS)&lt;br /&gt;
   Main PID: 88906 (haproxy)&lt;br /&gt;
      Tasks: 5 (limit: 9327)&lt;br /&gt;
     Memory: 9.4M&lt;br /&gt;
     CGroup: /system.slice/haproxy.service&lt;br /&gt;
             ├─88906 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -S /run/haproxy-master.sock&lt;br /&gt;
             └─88916 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -S /run/haproxy-master.sock&lt;br /&gt;
&lt;br /&gt;
May 19 10:36:36 haproxy-01 haproxy[88906]: Proxy back_ad53goaccess started.&lt;br /&gt;
May 19 10:36:36 haproxy-01 haproxy[88906]: Proxy back_ad53goaccess started.&lt;br /&gt;
May 19 10:36:36 haproxy-01 haproxy[88906]: Proxy back_salledelecturearchiveslamayenne started.&lt;br /&gt;
May 19 10:36:36 haproxy-01 haproxy[88906]: Proxy back_salledelecturearchiveslamayenne started.&lt;br /&gt;
May 19 10:36:36 haproxy-01 haproxy[88906]: Proxy back_ad53internetpublicationajlsm started.&lt;br /&gt;
May 19 10:36:36 haproxy-01 haproxy[88906]: Proxy back_ad53internetpublicationajlsm started.&lt;br /&gt;
May 19 10:36:36 haproxy-01 haproxy[88906]: Proxy back_ad53preprodajlsm started.&lt;br /&gt;
May 19 10:36:36 haproxy-01 haproxy[88906]: Proxy back_ad53preprodajlsm started.&lt;br /&gt;
May 19 10:36:36 haproxy-01 haproxy[88906]: Proxy back_ad53slecturepublicationajlsm started.&lt;br /&gt;
May 19 10:36:36 haproxy-01 haproxy[88906]: Proxy back_ad53slecturepublicationajlsm started.&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Tester un domaine en passant par le reverse proxy HAPROXY == &lt;br /&gt;
(sans avoir à faire une migration PROD / sans impact CLIENT).&lt;br /&gt;
&lt;br /&gt;
Les tests sont lancés depuis votre poste de travail en suivant les instructions ci-dessous.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Exemple : Tests sur la VM Port Dunkerque&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Rajouter cette ligne dans le fichier hosts du poste de travail d&#039;où seront lancés les tests :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;51.83.117.120 port-dunkerque.pleade.com&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{remarque|Pour info, cette IP 51.83.117.120 pointe sur l&#039;IP redondée du HAPROXY soit 10.0.0.32.}}&lt;br /&gt;
Il faut bien tester pour détecter d&#039;éventuels faux positifs (logs : {{path|/var/log/haproxy.log}})&lt;br /&gt;
== Réplication de la configuration dans les 2 Haproxy ==&lt;br /&gt;
Une fois la configuration {{path|/etc/haproxy/haproxy.cfg}} testée et validée dans le Haproxy01, répliquez cette configuration dans Haproxy02.&lt;br /&gt;
== Ansible ==&lt;br /&gt;
=== Réplication avec ansile ===&lt;br /&gt;
{{important|Source V1 pour l&#039;ansibelisation du déploiement Haproxy dans le SVN sous le nom : {{path|ansible-ajlsm/trunk/ansible-ajlsm-haproxy}}.&lt;br /&gt;
&lt;br /&gt;
Après chaque modification, pensez à commiter !!!}}&lt;br /&gt;
&lt;br /&gt;
{{notice|Ne pas oublier de changer les mots de passes dans inventory/ajlsm_loadbalancer.inventory (à terme il faudra utiliser des clés publiques ainsi qu&#039;Ansible-Vault)}}&lt;br /&gt;
==== Installation de Ansible ====&lt;br /&gt;
Il faut installer Ansible au préalable ( https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#installing-ansible-on-ubuntu )&lt;br /&gt;
==== Paramétrage de Ansible ====&lt;br /&gt;
#Ajouter la variable d&#039;environnement.&lt;br /&gt;
#Modifier les clés dans le fichier ansible-ajlsm-haproxy/inventory/ajlsm_loadbalancer.inventory&lt;br /&gt;
&lt;br /&gt;
==== Variabilisation ====&lt;br /&gt;
Par exemple, les IP pour le traitement des accès par IP et blocage, on variabilise la configuration dans Haproxy en ajoutant, Dans le fichier {{path|/ansible-ajlsm-haproxy/inventory/group_vars/ajlsm_loadbalancer/haproxy.yml}} et juste avant {{var|frontend front_web}} :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;---&lt;br /&gt;
haproxy_allowed_ips_ajlsm: &amp;quot; xx.xx.xx.xx xx.xx.xx.xx xx.xx.xx.xx/xx&amp;quot;&lt;br /&gt;
haproxy_allowed_ips_[le-client]_client: &amp;quot;xx.xx.xx.xx&amp;quot;&lt;br /&gt;
haproxy_custom_configuration: |&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Puis en ajoutant, dans le frontend front_web et avant les autres acl, l&#039;instruction suivante :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;        acl allowed_ajlsm src {{ haproxy_allowed_ips_ajlsm }}&lt;br /&gt;
        acl allowed_[le-client]_client src {{ haproxy_allowed_ips_[le-client]_client }}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Par exemple, pour AJLSM et ad53 :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;---&lt;br /&gt;
haproxy_allowed_ips_ajlsm: &amp;quot;82.65.94.250 109.190.129.96 91.174.149.42 10.0.0.0/24&amp;quot;&lt;br /&gt;
haproxy_allowed_ips_ad53_client: &amp;quot;85.115.60.201&amp;quot;&lt;br /&gt;
haproxy_custom_configuration: |&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
        acl allowed_ajlsm src {{ haproxy_allowed_ips_ajlsm }}&lt;br /&gt;
        acl allowed_ad53_client src {{ haproxy_allowed_ips_ad53_client }}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==== Réplication ====&lt;br /&gt;
#Il faut être sous VPN. &lt;br /&gt;
#Dans {{path|/etc/host}}, ajouter les 2 hosts : 10.0.0.30	haproxy01.ajlsm.lan, et : 10.0.0.31	haproxy02.ajlsm.lan&lt;br /&gt;
#Après avoir testé la configuration dans Haproxy01, créer le fichier Haproxy.yml (copie du fichier Haproxy01 en retirant les sections &amp;quot;global&amp;quot; et &amp;quot;default&amp;quot;) et ajoutant les variables, si nécessaire.&lt;br /&gt;
#Le fichier Haproxy.yml doit être placé dans le répertoire {{path|/ansible-ajlsm-haproxy/inventory/group_vars/ajlsm_loadbalancer/haproxy.yml}}&lt;br /&gt;
#Lancer la commande depuis la racine du dossier décompressé (il faut avoir ansible.cfg en visu lorqu&#039;on fait un ls).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;ansible-playbook ./plays/deploy.haproxy.yml -l ajlsm_loadbalancer&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{notice|Il faut un environnement python. Penser à lancer &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;source .venv/bin/activate&amp;lt;/syntaxhighlight&amp;gt; si vous travaillez dans un environnement spécifique}}&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;source .venv/bin/activate &amp;amp;&amp;amp; ansible-playbook ./plays/deploy.haproxy.yml -l ajlsm_loadbalancer&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Si tout va bien :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;ansible-ajlsm-haproxy ~$ ansible-playbook ./plays/deploy.haproxy.yml -l ajlsm_loadbalancer&lt;br /&gt;
&lt;br /&gt;
PLAY [ajlsm_loadbalancer] ****************************************************************************************************************************************************************************************************************&lt;br /&gt;
&lt;br /&gt;
TASK [Gathering Facts] *******************************************************************************************************************************************************************************************************************&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [haproxy : Install packages] ********************************************************************************************************************************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [haproxy : Deploy configuration and validate it] ************************************************************************************************************************************************************************************&lt;br /&gt;
changed: [haproxy02.ajlsm.lan]&lt;br /&gt;
changed: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [haproxy : Restore configuration (validation failed)] *******************************************************************************************************************************************************************************&lt;br /&gt;
skipping: [haproxy01.ajlsm.lan]&lt;br /&gt;
skipping: [haproxy02.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [haproxy : Remove restored backup file] *********************************************************************************************************************************************************************************************&lt;br /&gt;
skipping: [haproxy01.ajlsm.lan]&lt;br /&gt;
skipping: [haproxy02.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [haproxy : Start service and enable it on boot] *************************************************************************************************************************************************************************************&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [haproxy : Failure] *****************************************************************************************************************************************************************************************************************&lt;br /&gt;
skipping: [haproxy01.ajlsm.lan]&lt;br /&gt;
skipping: [haproxy02.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
RUNNING HANDLER [haproxy : restart haproxy] **********************************************************************************************************************************************************************************************&lt;br /&gt;
changed: [haproxy02.ajlsm.lan]&lt;br /&gt;
changed: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
PLAY RECAP *******************************************************************************************************************************************************************************************************************************&lt;br /&gt;
haproxy01.ajlsm.lan        : ok=5    changed=2    unreachable=0    failed=0    skipped=3    rescued=0    ignored=0   &lt;br /&gt;
haproxy02.ajlsm.lan        : ok=5    changed=2    unreachable=0    failed=0    skipped=3    rescued=0    ignored=0   &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== En cas d&#039;erreur après le lancement de la commande ==== &lt;br /&gt;
===== Essayer la commande ===== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;ANSIBLE_CONFIG=ansible.cfg ansible-playbook ./plays/deploy.haproxy.yml -l ajlsm_loadbalancer&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette partie est à compléter selon l&#039;évolution du script de déploiement.&lt;br /&gt;
===== 1 - Si la commande renvoie : =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;-bash: ansible-playbook: command not found&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Voir tuto : https://stackoverflow.com/questions/63177609/zsh-command-not-found-ansible-after-pip-installing&lt;br /&gt;
===== 2 - Si la commande renvoie : =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;ansible-playbook ./plays/deploy.haproxy.yml -l ajlsm_loadbalancer&lt;br /&gt;
&lt;br /&gt;
PLAY [ajlsm_loadbalancer] *****************************************************************************************************************************************************************************************************************************&lt;br /&gt;
&lt;br /&gt;
TASK [Gathering Facts] ********************************************************************************************************************************************************************************************************************************&lt;br /&gt;
fatal: [haproxy01.ajlsm.lan]: UNREACHABLE! =&amp;gt; {&amp;quot;changed&amp;quot;: false, &amp;quot;msg&amp;quot;: &amp;quot;Failed to connect to the host via ssh: ssh: Could not resolve hostname haproxy01.ajlsm.lan: nodename nor servname provided, or not known&amp;quot;, &amp;quot;unreachable&amp;quot;: true}&lt;br /&gt;
fatal: [haproxy02.ajlsm.lan]: UNREACHABLE! =&amp;gt; {&amp;quot;changed&amp;quot;: false, &amp;quot;msg&amp;quot;: &amp;quot;Failed to connect to the host via ssh: ssh: Could not resolve hostname haproxy02.ajlsm.lan: nodename nor servname provided, or not known&amp;quot;, &amp;quot;unreachable&amp;quot;: true}&lt;br /&gt;
&lt;br /&gt;
PLAY RECAP ********************************************************************************************************************************************************************************************************************************************&lt;br /&gt;
haproxy01.ajlsm.lan        : ok=0    changed=0    unreachable=1    failed=0    skipped=0    rescued=0    ignored=0   &lt;br /&gt;
haproxy02.ajlsm.lan        : ok=0    changed=0    unreachable=1    failed=0    skipped=0    rescued=0    ignored=0&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dans {{path|/etc/host}}, ajouter les 2 hosts : &lt;br /&gt;
#10.0.0.30 haproxy01.ajlsm.lan&lt;br /&gt;
#10.0.0.31 haproxy02.ajlsm.lan&lt;br /&gt;
&lt;br /&gt;
==== Reste à faire ====&lt;br /&gt;
Fine-tuning pour une maintenance simplifiée + le vault&amp;amp;clé publique pour la sécurité des mots de passes&lt;br /&gt;
# Il faudrait vaulter des choses,  &lt;br /&gt;
# améliorer le playbook &amp;amp; le rôle  &lt;br /&gt;
# ainsi que variabiliser plus de choses;&lt;br /&gt;
&lt;br /&gt;
== Migrer un site vers HAPROXY (mise en production) == &lt;br /&gt;
(après avoir testé)&lt;br /&gt;
&lt;br /&gt;
* Soit changer le DNS vers 51.83.117.120 (le client doit faire pointer son DNS sur cette IP)&lt;br /&gt;
* Soit aller dans les NAT One-to-One (1:1) d&#039;OPNSENSE, et changer l&#039;IP du client vers 10.0.0.32 (sur la correspondance IP externe client &amp;lt;-&amp;gt; IP interne client de la page)&lt;br /&gt;
Lors d&#039;une mise en production, pour éviter faire changer aux clients le DNS tout de suite et pour garder un débrayage facile : depuis le pare-feu OPNSense -&amp;gt; firewall -&amp;gt; NAT -&amp;gt; one-to-one, on fait pointer l&#039;IP initiale de la VM vers 10.0.0.32. &lt;br /&gt;
&lt;br /&gt;
Dans l&#039;exemple pour PORT DUNKERQUE, ça voudrait dire faire pointer 46.105.188.170 sur 10.0.0.32 au lieu de 10.0.0.24.&lt;br /&gt;
&lt;br /&gt;
Voir la copie d&#039;écran de OPNSense : [[media:Nat.png]]&lt;br /&gt;
&lt;br /&gt;
== Arrêter le WAF ==&lt;br /&gt;
En cas de problème avec une VM client (un blocage, ralentissement, faux positifs, etc.)&lt;br /&gt;
* Modifier les configuration apache en décommentant &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;#RewriteRule .* /403.html [R,L]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
et en remettant les règles pour les logs (commenter la section et décommenter l&#039;autre) :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;       # Configuration des logs pour suivi par IP utilisateurs&lt;br /&gt;
        #RemoteIPHeader X-Forwarded-For&lt;br /&gt;
        #LogFormat &amp;quot;%a %l %u %t \&amp;quot;%r\&amp;quot; %&amp;gt;s %b \&amp;quot;%{Referer}i\&amp;quot; \&amp;quot;%{User-Agent}i\&amp;quot;&amp;quot; forwarded&lt;br /&gt;
&lt;br /&gt;
        #ErrorLog /var/log/apache2/chercher-archives.lamayenne.fr.errors.log&lt;br /&gt;
        #CustomLog /var/log/apache2/chercher-archives.lamayenne.fr.log forwarded&lt;br /&gt;
        # Fin configuration des logs pour suivi par IP utilisateurs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        #### Configuration log hors WAF &lt;br /&gt;
        ErrorLog /var/log/apache2/archives.lamayenne.fr.errors.log&lt;br /&gt;
        CustomLog /var/log/apache2/archives.lamayenne.fr.log combined&lt;br /&gt;
        #### Fin configuration log hors WAF &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Remettre l&#039;IP interne du client (et pas celle du HAPROXY) dans le NAT 1:1 d&#039;OPNSENSE. &lt;br /&gt;
* Ou bien, éteindre les deux machines VM modsec-spoe (Proxmox Saturne) pour désactiver le WAF de force.&lt;br /&gt;
== Faux positifs ==&lt;br /&gt;
On parle de &amp;quot;faux positif &amp;quot; lorsque un paquet anodin (ne constituant aucune menace réelle) est détecté comme tentative d&#039;intrusion.&lt;br /&gt;
&lt;br /&gt;
On parle de &amp;quot;faux négatif&amp;quot; lorsqu&#039;une tentative d&#039;intrusion n&#039;est pas détectée.&lt;br /&gt;
&lt;br /&gt;
{{important|En attente de la nouvelle documentation de Coraza}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Gestion d&#039;un faux positif Coraza (OWASP CRS) sur Archives de la Mayenne =&lt;br /&gt;
&lt;br /&gt;
== Contexte ==&lt;br /&gt;
&lt;br /&gt;
L&#039;application Archives de la Mayenne (Drupal + Pleade/Lucene) générait une erreur HTTP 403 sur certaines recherches contenant :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Saint-Vénérand (Laval)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le WAF Coraza détectait à tort une tentative d&#039;injection SQL car la chaîne :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Vénérand (&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
contient le motif :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
rand (&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
qui correspond à une signature SQL de la règle OWASP CRS 942151.&lt;br /&gt;
&lt;br /&gt;
== Identification du faux positif ==&lt;br /&gt;
&lt;br /&gt;
Recherche dans les logs Coraza :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
tail -f /var/log/coraza-spoa/coraza-agent.log&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Extrait du log :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;rule_id&amp;quot;:942151,&lt;br /&gt;
  &amp;quot;msg&amp;quot;:&amp;quot;SQL Injection Attack: SQL function name detected&amp;quot;,&lt;br /&gt;
  &amp;quot;data&amp;quot;:&amp;quot;Matched Data: rand ( found within ARGS:fquery1: Saint-Vénérand (Laval)&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La règle responsable est :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
942151 - SQL Injection Attack: SQL function name detected&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Localisation de la configuration Coraza ==&lt;br /&gt;
&lt;br /&gt;
Service :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl status coraza-spoa&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Configuration principale :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/etc/coraza-spoa/config.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Extrait :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
Include /etc/coraza-spoa/custom-rules/*.conf&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le fichier de règles est généré automatiquement par Ansible :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/etc/coraza-spoa/custom-rules/900-runtime-overrides.conf&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Localisation de la source Ansible ==&lt;br /&gt;
&lt;br /&gt;
Recherche de la variable :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
grep -R &amp;quot;coraza_spoa_custom_rules_request_body_exclusions&amp;quot; -n .&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
roles/coraza/templates/custom-rules.conf.j2&lt;br /&gt;
inventory/group_vars/ajlsm_loadbalancer/coraza.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Template générateur :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
roles/coraza/templates/custom-rules.conf.j2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variables du groupe load balancer :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
inventory/group_vars/ajlsm_loadbalancer/coraza.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Vérification de la prise en compte de la variable ==&lt;br /&gt;
&lt;br /&gt;
Contrôle de la variable vue par Ansible :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible -i inventory haproxy01.ajlsm.lan \&lt;br /&gt;
  -m debug \&lt;br /&gt;
  -a &#039;var=coraza_spoa_custom_rules_request_body_exclusions&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La nouvelle règle doit apparaître dans la sortie.&lt;br /&gt;
&lt;br /&gt;
== Ajout de l&#039;exception ==&lt;br /&gt;
&lt;br /&gt;
Modification du fichier :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
inventory/group_vars/ajlsm_loadbalancer/coraza.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ajout dans la section :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
coraza_spoa_custom_rules_request_body_exclusions:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Règle finale retenue :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
  - id: 123471&lt;br /&gt;
    variable: &amp;quot;REQUEST_FILENAME&amp;quot;&lt;br /&gt;
    operator: &amp;quot;@rx&amp;quot;&lt;br /&gt;
    pattern: &amp;quot;^/(archives-en-ligne|pleade)/.*results(\\.html|\\.ajax-html)$&amp;quot;&lt;br /&gt;
    actions: &amp;quot;nolog,pass,ctl:ruleRemoveTargetById=942151;ARGS:/^(?:query[0-9]+|fquery[0-9]+)$/&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette règle :&lt;br /&gt;
&lt;br /&gt;
* s&#039;applique aux pages de résultats Pleade ;&lt;br /&gt;
* couvre les pages HTML classiques et les appels AJAX ;&lt;br /&gt;
* retire la règle CRS 942151 ;&lt;br /&gt;
* uniquement pour le paramètre ARGS:fquery1 ;&lt;br /&gt;
* conserve toutes les autres protections CRS.&lt;br /&gt;
&lt;br /&gt;
Exemples d&#039;URLs couvertes :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/archives-en-ligne/custom-results.html&lt;br /&gt;
/archives-en-ligne/results.html&lt;br /&gt;
/archives-en-ligne/functions/ead/custom-results.ajax-html&lt;br /&gt;
/pleade/custom-results.html&lt;br /&gt;
/pleade/functions/ead/custom-results.ajax-html&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ainsi que les motifs suivants :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
ARGS:query1&lt;br /&gt;
ARGS:query2&lt;br /&gt;
ARGS:query3&lt;br /&gt;
ARGS:fquery1&lt;br /&gt;
ARGS:fquery2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Vérification du rendu du template ==&lt;br /&gt;
&lt;br /&gt;
Simulation du déploiement :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook \&lt;br /&gt;
  -i inventory \&lt;br /&gt;
  ./plays/deploy.coraza.yml \&lt;br /&gt;
  --limit haproxy01.ajlsm.lan \&lt;br /&gt;
  --check \&lt;br /&gt;
  --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le diff doit montrer :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;apache&amp;quot;&amp;gt;&lt;br /&gt;
SecRule REQUEST_FILENAME &amp;quot;@rx ^/(archives-en-ligne|pleade)/.*results(\.html|\.ajax-html)$&amp;quot; \&lt;br /&gt;
  &amp;quot;id:123471,phase:1,nolog,pass,ctl:ruleRemoveTargetById=942151;ARGS:/^(?:query[0-9]+|fquery[0-9]+)$/&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Déploiement ==&lt;br /&gt;
&lt;br /&gt;
Attention : le rôle Coraza est indépendant du rôle HAProxy.&lt;br /&gt;
&lt;br /&gt;
Le playbook HAProxy :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
plays/deploy.haproxy.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ne déploie pas les règles Coraza.&lt;br /&gt;
&lt;br /&gt;
Le playbook Coraza est :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
plays/deploy.coraza.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Déploiement sur tous les load balancers :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook \&lt;br /&gt;
  -i inventory \&lt;br /&gt;
  ./plays/deploy.coraza.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer \&lt;br /&gt;
  --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Déploiement uniquement sur haproxy01 :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook \&lt;br /&gt;
  -i inventory \&lt;br /&gt;
  ./plays/deploy.coraza.yml \&lt;br /&gt;
  --limit haproxy01.ajlsm.lan \&lt;br /&gt;
  --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Déploiement uniquement sur haproxy02 :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook \&lt;br /&gt;
  -i inventory \&lt;br /&gt;
  ./plays/deploy.coraza.yml \&lt;br /&gt;
  --limit haproxy02.ajlsm.lan \&lt;br /&gt;
  --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Vérifications après déploiement ==&lt;br /&gt;
&lt;br /&gt;
Contrôle de la présence de la règle :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
grep -R &amp;quot;123471\|942151&amp;quot; /etc/coraza-spoa/custom-rules -n&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat attendu :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/etc/coraza-spoa/custom-rules/900-runtime-overrides.conf:&lt;br /&gt;
SecRule REQUEST_FILENAME &amp;quot;@rx ^/(archives-en-ligne|pleade)/.*results(\.html|\.ajax-html)$&amp;quot; \&lt;br /&gt;
&amp;quot;id:123471,...ctl:ruleRemoveTargetById=942151;ARGS:fquery1&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Contrôle du service :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl status coraza-spoa&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérification via Ansible :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible -i inventory ajlsm_loadbalancer \&lt;br /&gt;
  -m shell \&lt;br /&gt;
  -a &#039;grep -R &amp;quot;123471\|942151&amp;quot; /etc/coraza-spoa/custom-rules -n &amp;amp;&amp;amp; systemctl is-active coraza-spoa&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Validation fonctionnelle ==&lt;br /&gt;
&lt;br /&gt;
Tester la recherche :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Saint-Vénérand (Laval)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;URL principale ne doit plus renvoyer de 403 :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/archives-en-ligne/custom-results.html&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les appels AJAX associés ne doivent plus être bloqués :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/archives-en-ligne/functions/ead/custom-results.ajax-html&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les logs Coraza ne doivent plus contenir de déclenchement de la règle 942151 pour le paramètre :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
ARGS:fquery1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Points importants ==&lt;br /&gt;
&lt;br /&gt;
* Les règles Coraza sont gérées par Ansible.&lt;br /&gt;
* Toute modification manuelle dans /etc/coraza-spoa/custom-rules/ sera écrasée lors d&#039;un prochain déploiement.&lt;br /&gt;
* La source de vérité est :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
inventory/group_vars/ajlsm_loadbalancer/coraza.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Les déploiements de configuration HAProxy et Coraza sont indépendants.&lt;br /&gt;
* Une modification des règles Coraza nécessite l&#039;exécution du playbook :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
plays/deploy.coraza.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sur le poste local, dans le répertoire ansible-ajlsm, lancez :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.coraza.yml --limit ajlsm_loadbalancer --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.coraza.yml --limit ajlsm_loadbalancer --diff&lt;br /&gt;
&lt;br /&gt;
PLAY [Deploy Coraza SPOA WAF] ***************************************************************************************************************************&lt;br /&gt;
&lt;br /&gt;
TASK [Gathering Facts] **********************************************************************************************************************************&lt;br /&gt;
[WARNING]: Host &#039;haproxy02.ajlsm.lan&#039; is using the discovered Python interpreter at &#039;/usr/bin/python3.10&#039;, but future installation of another Python interpreter could cause a different interpreter to be discovered. See https://docs.ansible.com/ansible-core/2.20/reference_appendices/interpreter_discovery.html for more information.&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
[WARNING]: Host &#039;haproxy01.ajlsm.lan&#039; is using the discovered Python interpreter at &#039;/usr/bin/python3.10&#039;, but future installation of another Python interpreter could cause a different interpreter to be discovered. See https://docs.ansible.com/ansible-core/2.20/reference_appendices/interpreter_discovery.html for more information.&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Install build dependencies] **************************************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Install Go via snap] *********************************************************************************************************************&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Create build directory] ******************************************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Clone coraza-spoa repository] ************************************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Check if coraza-spoa binary already exists] **********************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Build coraza-spoa] ***********************************************************************************************************************&lt;br /&gt;
skipping: [haproxy01.ajlsm.lan]&lt;br /&gt;
skipping: [haproxy02.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Install coraza-spoa binary] **************************************************************************************************************&lt;br /&gt;
skipping: [haproxy01.ajlsm.lan]&lt;br /&gt;
skipping: [haproxy02.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Create coraza-spoa group] ****************************************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Create coraza-spoa user] *****************************************************************************************************************&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Create configuration directory] **********************************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Create log directories] ******************************************************************************************************************&lt;br /&gt;
ok: [haproxy01.ajlsm.lan] =&amp;gt; (item=/var/log/coraza-spoa)&lt;br /&gt;
ok: [haproxy02.ajlsm.lan] =&amp;gt; (item=/var/log/coraza-spoa)&lt;br /&gt;
ok: [haproxy02.ajlsm.lan] =&amp;gt; (item=/var/log/coraza-spoa/audit)&lt;br /&gt;
ok: [haproxy01.ajlsm.lan] =&amp;gt; (item=/var/log/coraza-spoa/audit)&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Create log files] ************************************************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan] =&amp;gt; (item=server.log)&lt;br /&gt;
ok: [haproxy01.ajlsm.lan] =&amp;gt; (item=server.log)&lt;br /&gt;
ok: [haproxy01.ajlsm.lan] =&amp;gt; (item=error.log)&lt;br /&gt;
ok: [haproxy02.ajlsm.lan] =&amp;gt; (item=error.log)&lt;br /&gt;
ok: [haproxy01.ajlsm.lan] =&amp;gt; (item=audit.log)&lt;br /&gt;
ok: [haproxy02.ajlsm.lan] =&amp;gt; (item=audit.log)&lt;br /&gt;
ok: [haproxy01.ajlsm.lan] =&amp;gt; (item=debug.log)&lt;br /&gt;
ok: [haproxy02.ajlsm.lan] =&amp;gt; (item=debug.log)&lt;br /&gt;
ok: [haproxy01.ajlsm.lan] =&amp;gt; (item=coraza-agent.log)&lt;br /&gt;
ok: [haproxy02.ajlsm.lan] =&amp;gt; (item=coraza-agent.log)&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Create rollback backup directory] ********************************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Deploy coraza.cfg for HAProxy] ***********************************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Check if current coraza-spoa config exists] **********************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Check if current custom rules file exists] ***********************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Backup current coraza-spoa config] *******************************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Backup current custom rules file] ********************************************************************************************************&lt;br /&gt;
changed: [haproxy01.ajlsm.lan]&lt;br /&gt;
changed: [haproxy02.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Deploy coraza-spoa config.yaml] **********************************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Create custom rules directory] ***********************************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Deploy custom rules] *********************************************************************************************************************&lt;br /&gt;
--- before: /etc/coraza-spoa/custom-rules/900-runtime-overrides.conf&lt;br /&gt;
+++ after: /Users/jlarvers/.ansible/tmp/ansible-local-20994a3e3jiy7/tmp2vqgd1ck/custom-rules.conf.j2&lt;br /&gt;
@@ -47,7 +47,7 @@&lt;br /&gt;
 SecRule REQUEST_FILENAME &amp;quot;@rx /full_html?&amp;quot; \&lt;br /&gt;
   &amp;quot;id:123470,phase:1,nolog,pass,ctl:requestBodyAccess=Off&amp;quot;&lt;br /&gt;
 SecRule REQUEST_FILENAME &amp;quot;@rx ^/(archives-en-ligne|pleade)/.*results(\.html|\.ajax-html)$&amp;quot; \&lt;br /&gt;
-  &amp;quot;id:123471,phase:1,nolog,pass,ctl:ruleRemoveTargetById=942151;ARGS:fquery1&amp;quot;&lt;br /&gt;
+  &amp;quot;id:123471,phase:1,nolog,pass,ctl:ruleRemoveTargetById=942151;ARGS:/^(?:query[0-9]+|fquery[0-9]+)$/&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 SecRequestBodyLimit 524288000&lt;br /&gt;
 SecRequestBodyNoFilesLimit 524288000&lt;br /&gt;
&lt;br /&gt;
changed: [haproxy02.ajlsm.lan]&lt;br /&gt;
--- before: /etc/coraza-spoa/custom-rules/900-runtime-overrides.conf&lt;br /&gt;
+++ after: /Users/jlarvers/.ansible/tmp/ansible-local-20994a3e3jiy7/tmpd0a58h10/custom-rules.conf.j2&lt;br /&gt;
@@ -47,7 +47,7 @@&lt;br /&gt;
 SecRule REQUEST_FILENAME &amp;quot;@rx /full_html?&amp;quot; \&lt;br /&gt;
   &amp;quot;id:123470,phase:1,nolog,pass,ctl:requestBodyAccess=Off&amp;quot;&lt;br /&gt;
 SecRule REQUEST_FILENAME &amp;quot;@rx ^/(archives-en-ligne|pleade)/.*results(\.html|\.ajax-html)$&amp;quot; \&lt;br /&gt;
-  &amp;quot;id:123471,phase:1,nolog,pass,ctl:ruleRemoveTargetById=942151;ARGS:fquery1&amp;quot;&lt;br /&gt;
+  &amp;quot;id:123471,phase:1,nolog,pass,ctl:ruleRemoveTargetById=942151;ARGS:/^(?:query[0-9]+|fquery[0-9]+)$/&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 SecRequestBodyLimit 524288000&lt;br /&gt;
 SecRequestBodyNoFilesLimit 524288000&lt;br /&gt;
&lt;br /&gt;
changed: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Remove legacy split custom rules files] **************************************************************************************************&lt;br /&gt;
ok: [haproxy01.ajlsm.lan] =&amp;gt; (item=900-legacy-overrides.conf)&lt;br /&gt;
ok: [haproxy02.ajlsm.lan] =&amp;gt; (item=900-legacy-overrides.conf)&lt;br /&gt;
ok: [haproxy01.ajlsm.lan] =&amp;gt; (item=900-exclusions.conf)&lt;br /&gt;
ok: [haproxy02.ajlsm.lan] =&amp;gt; (item=900-exclusions.conf)&lt;br /&gt;
ok: [haproxy01.ajlsm.lan] =&amp;gt; (item=910-crs-policy.conf)&lt;br /&gt;
ok: [haproxy02.ajlsm.lan] =&amp;gt; (item=910-crs-policy.conf)&lt;br /&gt;
ok: [haproxy01.ajlsm.lan] =&amp;gt; (item=920-body-limits.conf)&lt;br /&gt;
ok: [haproxy02.ajlsm.lan] =&amp;gt; (item=920-body-limits.conf)&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Validate coraza-spoa config and custom rules before restart] *****************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Deploy coraza-spoa systemd unit] *********************************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Enable and start coraza-spoa service] ****************************************************************************************************&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
RUNNING HANDLER [coraza : Restart coraza-spoa] **********************************************************************************************************&lt;br /&gt;
changed: [haproxy01.ajlsm.lan]&lt;br /&gt;
changed: [haproxy02.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
PLAY RECAP **********************************************************************************************************************************************&lt;br /&gt;
haproxy01.ajlsm.lan        : ok=25   changed=3    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0   &lt;br /&gt;
haproxy02.ajlsm.lan        : ok=25   changed=3    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Les paramètres suivants puvent être utilisés avec ansible :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Option&lt;br /&gt;
! Description&lt;br /&gt;
! Modifie le serveur&lt;br /&gt;
! Affiche les différences&lt;br /&gt;
! Usage typique&lt;br /&gt;
|-&lt;br /&gt;
| aucune option&lt;br /&gt;
| Exécution normale du playbook&lt;br /&gt;
| Oui&lt;br /&gt;
| Non&lt;br /&gt;
| Déploiement standard&lt;br /&gt;
|-&lt;br /&gt;
| --check&lt;br /&gt;
| Simulation (dry-run)&lt;br /&gt;
| Non&lt;br /&gt;
| Non&lt;br /&gt;
| Vérifier ce qui serait modifié&lt;br /&gt;
|-&lt;br /&gt;
| --diff&lt;br /&gt;
| Exécution réelle avec affichage des différences&lt;br /&gt;
| Oui&lt;br /&gt;
| Oui&lt;br /&gt;
| Déployer en visualisant les changements&lt;br /&gt;
|-&lt;br /&gt;
| --check --diff&lt;br /&gt;
| Simulation avec affichage des différences&lt;br /&gt;
| Non&lt;br /&gt;
| Oui&lt;br /&gt;
| Vérifier précisément les modifications avant déploiement&lt;br /&gt;
|-&lt;br /&gt;
| --limit &amp;lt;hôte&amp;gt;&lt;br /&gt;
| Limite l&#039;exécution à un ou plusieurs hôtes&lt;br /&gt;
| Selon les autres options&lt;br /&gt;
| Selon les autres options&lt;br /&gt;
| Tester sur un seul serveur&lt;br /&gt;
|-&lt;br /&gt;
| --tags &amp;lt;tag&amp;gt;&lt;br /&gt;
| Exécute uniquement les tâches portant un tag donné&lt;br /&gt;
| Selon les autres options&lt;br /&gt;
| Selon les autres options&lt;br /&gt;
| Déployer uniquement un composant spécifique&lt;br /&gt;
|-&lt;br /&gt;
| --skip-tags &amp;lt;tag&amp;gt;&lt;br /&gt;
| Ignore les tâches portant un tag donné&lt;br /&gt;
| Selon les autres options&lt;br /&gt;
| Selon les autres options&lt;br /&gt;
| Exclure une partie du playbook&lt;br /&gt;
|-&lt;br /&gt;
| -v&lt;br /&gt;
| Mode verbeux&lt;br /&gt;
| Selon les autres options&lt;br /&gt;
| Selon les autres options&lt;br /&gt;
| Voir davantage d&#039;informations&lt;br /&gt;
|-&lt;br /&gt;
| -vv&lt;br /&gt;
| Mode très verbeux&lt;br /&gt;
| Selon les autres options&lt;br /&gt;
| Selon les autres options&lt;br /&gt;
| Débogage&lt;br /&gt;
|-&lt;br /&gt;
| -vvv&lt;br /&gt;
| Mode débogage avancé&lt;br /&gt;
| Selon les autres options&lt;br /&gt;
| Selon les autres options&lt;br /&gt;
| Analyse détaillée des connexions et modules&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Coraza =&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=WAF_2026&amp;diff=6524</id>
		<title>WAF 2026</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=WAF_2026&amp;diff=6524"/>
		<updated>2026-11-05T14:31:26Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : /* Certificats automatiques (SSL Lets Encrypt) via Haproxy */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:Ansile]][[category:Haproxy]][[category:modsec]][[category:coraza]]&lt;br /&gt;
== Documentation externe ==&lt;br /&gt;
Voir Coraza : https://www.coraza.io/&lt;br /&gt;
[[category:letsencrypt]][[category:OPNsense]][[category:opnsens]][[category:opensens]][[category:opensense]]&lt;br /&gt;
WAF : Web Application Firewall.&lt;br /&gt;
&lt;br /&gt;
== Description de l&#039;infrastructure ==&lt;br /&gt;
=== Schéma de l&#039;infra ===&lt;br /&gt;
&lt;br /&gt;
Dans notre infra (aujourd&#039;hui Saturne3) et sur Proxmox, on a installé 4 VM. &lt;br /&gt;
&lt;br /&gt;
2 VM Haproxy (en cluster) récupèrent le flux et le renvoi vers 2 VM modsecurity (en cluster) qui analysent et traitent les requêtes et renvoient vers les VM HAPROXY qui renvoient, ou non, vers les VM clients.&lt;br /&gt;
&lt;br /&gt;
* Mise en place de deux nœuds Haproxy redondés via VRRP &lt;br /&gt;
# IP 1 : 10.0.0.30, &lt;br /&gt;
# IP 2 : 10.0.0.31, &lt;br /&gt;
# IP redondée/balancée : 10.0.0.32, IP externe redondée : 51.83.117.120)&lt;br /&gt;
{{important|Pré-requis pour les étapes suivantes :&lt;br /&gt;
# Accès par VPN Wireguard, ou,&lt;br /&gt;
# Accès par OpenVPN,&lt;br /&gt;
# Utilisateur root}}&lt;br /&gt;
&lt;br /&gt;
== Ajouts des certificats SSL (manuelle) ==&lt;br /&gt;
=== Rajouter un domaine (un certificat SSL) dans le reverse proxy HAPROXY ===&lt;br /&gt;
1 -&amp;gt; Copier le certificat complet (voir où se trouve les certificats dans la conf apache du domaine ...-le-ssl.conf, puis réunir la clé publique et la clé privée en 1 fichier. &lt;br /&gt;
&lt;br /&gt;
Depuis la VM (voir celui de portdunkerque pour exemple) vers les 2 VM HAPROXY,&lt;br /&gt;
dans {{path|/etc/haproxy/certs/}} en prenant soin de respecter le nom de domaine, par exemple :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;port-dunkerque.pleade.com.pem&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Une fois les certificats SSL en place, relancez le service haproxy :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;service haproxy reload&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{notice|Contrairement à la recommandation qui suit, l&#039;intégration du contenu des fichiers .crt, .key et .pem fonctionne très bien : Attention, ne pas ajouter le contenu du fichier .pem s&#039;il existe !}}&lt;br /&gt;
&lt;br /&gt;
==Certificats automatiques (SSL Lets Encrypt) via Haproxy==&lt;br /&gt;
{{important|Utiliser le projet Ansible : [[WAF#Ansible]]}}&lt;br /&gt;
{{important|Le domaine doit être géré par Haproxy. Il doit être &amp;quot;derrière&amp;quot; le pare-feu, c&#039;est-à-dire : Firewall: NAT: One-to-One : IP interne 10.0.0.32. Ne fonctionne pas avec l&#039;IP native du serveur.}}&lt;br /&gt;
===Modification du fichier haproxy.yml d&#039;Ansible===&lt;br /&gt;
# Le chemin des certificats change de /etc/haproxy/ssl à /etc/haproxy/certs&lt;br /&gt;
# Ajout de la clé ACCOUNT_THUMBPRINT qui gère les challenge acme-challenge&lt;br /&gt;
===Ajout de certificat sur un nouveau domaine===&lt;br /&gt;
L&#039;exemple ici porte sur port-dunkerque.pleade.com&lt;br /&gt;
{{important|A exécuter séquentiellement (un après l&#039;autre, pas en parallèle) sur HAPROXY-01 et HAPROXY-02}}&lt;br /&gt;
====S&#039;authentifier en tant qu&#039;acme====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;$ sudo -u acme -s                       /!\ IMPORTANT d&#039;être authentifié en tant qu&#039;acme&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
====Génération des certificats via LetsEncrypt====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;$ acme.sh --issue -d port-dunkerque.pleade.com --stateless --server letsencrypt&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
====Déploiement dans le dossier Haproxy grâce au hook correspondant qui met à jour à chaud les certs====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;$ DEPLOY_HAPROXY_HOT_UPDATE=yes DEPLOY_HAPROXY_STATS_SOCKET=/var/run/haproxy/admin.sock DEPLOY_HAPROXY_PEM_PATH=/etc/haproxy/certs  acme.sh --deploy -d port-dunkerque.pleade.com --deploy-hook haproxy&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{notice|Si, en tant qu&#039;acme, on fait un crontab -l, on peut voir qu&#039;une tâche de renouvellement de certificats tourne régulièrement.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Certificats Let&#039;s Encrypt automatiques via HAProxy&lt;br /&gt;
&lt;br /&gt;
## Présentation&lt;br /&gt;
&lt;br /&gt;
Les certificats TLS des domaines publiés par les serveurs HAProxy AJLSM sont gérés avec **acme.sh** et Let&#039;s Encrypt.&lt;br /&gt;
&lt;br /&gt;
L&#039;installation et le renouvellement des certificats s&#039;effectuent sur les deux serveurs :&lt;br /&gt;
&lt;br /&gt;
- `haproxy-01` — `10.0.0.30`&lt;br /&gt;
- `haproxy-02` — `10.0.0.31`&lt;br /&gt;
&lt;br /&gt;
Les certificats sont stockés dans `/etc/haproxy/certs/`.&lt;br /&gt;
&lt;br /&gt;
Le hook `haproxy` d&#039;acme.sh permet leur déploiement et leur mise à jour à chaud par le socket d&#039;administration HAProxy.&lt;br /&gt;
&lt;br /&gt;
**Important : les opérations doivent être effectuées successivement sur HAProxy-01 puis HAProxy-02, jamais en parallèle.** Chaque serveur possède sa propre installation d&#039;acme.sh et ses propres certificats.&lt;br /&gt;
&lt;br /&gt;
## 1. Prérequis&lt;br /&gt;
&lt;br /&gt;
### 1.1. Configuration réseau et DNS&lt;br /&gt;
&lt;br /&gt;
Le domaine doit :&lt;br /&gt;
&lt;br /&gt;
- disposer d&#039;un enregistrement DNS public pointant vers l&#039;adresse IP publique utilisée par l&#039;infrastructure ;&lt;br /&gt;
- être acheminé par OPNsense vers la VIP HAProxy `10.0.0.32` ;&lt;br /&gt;
- être pris en charge par la configuration HAProxy.&lt;br /&gt;
&lt;br /&gt;
La configuration du NAT dépend de l&#039;adresse publique concernée. Pour l&#039;installation CDF du 5 novembre 2026, le routage utilise **OPNsense Destination NAT**, et non NAT One-to-One.&lt;br /&gt;
&lt;br /&gt;
La validation Let&#039;s Encrypt utilise le challenge HTTP-01 en mode `stateless`, sur le port 80.&lt;br /&gt;
&lt;br /&gt;
### 1.2. Configuration HAProxy avec Ansible&lt;br /&gt;
&lt;br /&gt;
La configuration HAProxy est maintenue dans le projet Ansible AJLSM.&lt;br /&gt;
&lt;br /&gt;
Voir : `[[WAF#Ansible]]`&lt;br /&gt;
&lt;br /&gt;
Les éléments nécessaires comprennent :&lt;br /&gt;
&lt;br /&gt;
- le répertoire des certificats `/etc/haproxy/certs/` ;&lt;br /&gt;
- la clé `ACCOUNT_THUMBPRINT` utilisée pour la validation ACME ;&lt;br /&gt;
- la règle HTTP permettant de répondre aux requêtes `/.well-known/acme-challenge/` ;&lt;br /&gt;
- les ACL du domaine et son backend.&lt;br /&gt;
&lt;br /&gt;
La configuration Ansible doit être déployée et validée avant de demander le certificat.&lt;br /&gt;
&lt;br /&gt;
## 2. Création d&#039;un certificat&lt;br /&gt;
&lt;br /&gt;
Exemple : `cdf-recette.pleade.com`&lt;br /&gt;
&lt;br /&gt;
Toutes les commandes ci-dessous sont à effectuer sur **HAProxy-01**, puis à répéter sur **HAProxy-02**.&lt;br /&gt;
&lt;br /&gt;
### 2.1. Se connecter avec l&#039;utilisateur acme&lt;br /&gt;
&lt;br /&gt;
Depuis une session administrateur :&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo -u acme -s&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
**Important : les commandes acme.sh doivent être exécutées avec l&#039;utilisateur `acme`, et non avec `root`.**&lt;br /&gt;
&lt;br /&gt;
### 2.2. Demander le certificat Let&#039;s Encrypt&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
acme.sh --issue \&lt;br /&gt;
  -d cdf-recette.pleade.com \&lt;br /&gt;
  --stateless \&lt;br /&gt;
  --server letsencrypt&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Vérifier que la commande se termine par :&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Success&lt;br /&gt;
Cert success.&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Les fichiers du certificat sont enregistrés dans :&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/var/lib/acme/.acme.sh/cdf-recette.pleade.com_ecc/&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Ne pas modifier manuellement les fichiers de ce répertoire.&lt;br /&gt;
&lt;br /&gt;
### 2.3. Déployer le certificat dans HAProxy&lt;br /&gt;
&lt;br /&gt;
Toujours avec l&#039;utilisateur `acme` :&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
DEPLOY_HAPROXY_HOT_UPDATE=yes \&lt;br /&gt;
DEPLOY_HAPROXY_STATS_SOCKET=/var/run/haproxy/admin.sock \&lt;br /&gt;
DEPLOY_HAPROXY_PEM_PATH=/etc/haproxy/certs \&lt;br /&gt;
acme.sh --deploy \&lt;br /&gt;
  -d cdf-recette.pleade.com \&lt;br /&gt;
  --deploy-hook haproxy&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Le hook :&lt;br /&gt;
&lt;br /&gt;
1. prépare le certificat au format PEM ;&lt;br /&gt;
2. l&#039;installe dans `/etc/haproxy/certs/` ;&lt;br /&gt;
3. demande son chargement à chaud par HAProxy.&lt;br /&gt;
&lt;br /&gt;
Lors de l&#039;installation CDF du 5 novembre 2026, le déploiement a retourné :&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Deploying PEM file&lt;br /&gt;
Moving new certificate into place&lt;br /&gt;
Creating new certificate &#039;/etc/haproxy/certs/cdf-recette.pleade.com.pem&#039; over HAProxy stats socket.&lt;br /&gt;
Success&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Ce résultat confirme le succès de l&#039;opération de déploiement. Le fonctionnement HTTPS doit néanmoins être vérifié séparément.&lt;br /&gt;
&lt;br /&gt;
## 3. Vérifications&lt;br /&gt;
&lt;br /&gt;
### 3.1. Présence du certificat&lt;br /&gt;
&lt;br /&gt;
Depuis une session administrateur :&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ls -l /etc/haproxy/certs/cdf-recette.pleade.com.pem&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
###&lt;br /&gt;
&lt;br /&gt;
== Configuration de HaProxy - Méthode 1 ==&lt;br /&gt;
On utilise ansible pour générer les fichiers de configuration dans Haproxy, les appliquer, redémarrer les Haproxy, etc. &lt;br /&gt;
&lt;br /&gt;
[[WAF#Ansible|Voir la section : Ansible]]&lt;br /&gt;
&lt;br /&gt;
La configuration du fichier est la même, avec la possibilité de &lt;br /&gt;
# variabiliser : voir section : http://mw.ajlsm.com/wiki/WAF#Variabilisation&lt;br /&gt;
# déployer la configuration sur les 2 Haproxy en une seule action.&lt;br /&gt;
&lt;br /&gt;
Pour utiliser cette méthode, récupérer le projet &#039;&#039;&#039;ansible-ajlsm-haproxy&#039;&#039;&#039; en SVN.&lt;br /&gt;
&lt;br /&gt;
La création des règles est la même que celle décrite en méthode 2.&lt;br /&gt;
&lt;br /&gt;
La différence est que l&#039;on ne travaille pas &amp;quot;directement&amp;quot; dans le fichier {{path|/etc/haproxy/haproxy.cfg}}, mais dans le fichier {{path|/ansible-ajlsm-haproxy/inventory/group_vars/ajlsm_loadbalancer/haproxy.yml}} qui est déployé en ligne de commande avec Ansible. &lt;br /&gt;
&lt;br /&gt;
Cette méthode est celle utilisée en production.&lt;br /&gt;
&lt;br /&gt;
== Configuration de HaProxy - Méthode 2 ==&lt;br /&gt;
Voir aussi projet ansible en SVN : [[WAF#Ansible]].&lt;br /&gt;
 &lt;br /&gt;
Modifier directement le fichier de configuration configuration {{path|/etc/haproxy/haproxy.cfg}}.&lt;br /&gt;
&lt;br /&gt;
Rajouter les lignes suivantes dans la configuration {{path|/etc/haproxy/haproxy.cfg}} (dans les blocs {{path|frontend front_web}} et {{path|backend }}) :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
acl host_leclientvoulu hdr(host) -i lenomdedomaineduclientvoulu.com&lt;br /&gt;
use_backend back_leclientvoulu if host_leclientvoulu&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
et rajouter un nouveau bloc backend comme ceci :&lt;br /&gt;
# Configuration avec certificat SSL :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;backend back_leclientvoulu&lt;br /&gt;
   server LECLIENTVOULU ipduclientvoulu:443 check ssl verify none&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# Configuration sans certificat :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;backend back_leclientvoulu&lt;br /&gt;
   server LECLIENTVOULU ipduclientvoulu:80 check&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Par exemple, pour archives.lamayenne.fr :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;        acl host_ssl_archiveslamayenne  hdr(host)               -i          archives.lamayenne.fr&lt;br /&gt;
        use_backend back_ssl_archiveslamayenne                  if          host_ssl_archiveslamayenne&lt;br /&gt;
&lt;br /&gt;
        acl host_salledelecturearchiveslamayenne  hdr(host)       -i      salle-de-lecture-archives.lamayenne.fr&lt;br /&gt;
        use_backend back_salledelecturearchiveslamayenne          if      host_salledelecturearchiveslamayenne&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
backend back_ssl_archiveslamayenne&lt;br /&gt;
        server ARCHIVESLAMAYENNE                ad53.ajlsm.lan:443 check ssl verify none&lt;br /&gt;
&lt;br /&gt;
backend back_salledelecturearchiveslamayenne&lt;br /&gt;
        server SALLEDELECTUREARCHIVESLAMAYENNE  ad53.ajlsm.lan:80 check&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Traitement des blocages par IP ===&lt;br /&gt;
La règle apache pour le blocage des IP de chaque site : &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;RewriteCond %{REMOTE_ADDR}&amp;lt;/syntaxhighlight&amp;gt; renvoie sur le Haproxy. &lt;br /&gt;
&lt;br /&gt;
Le blocage d&#039;IP ne se fait plus. &lt;br /&gt;
&lt;br /&gt;
Lorsque toutes les IP doivent être bloquées sauf les accès prévus : pour le client, AJLSM, etc, (Par exemple, pour une application intranet) la &#039;&#039;&#039;gestion des accès par IP est à configurer dans Haproxy&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
De plus, les [[WAF#Modification_de_la_configuration_apache_des_domaines|configurations apache]] doivent être modifiées sur chaque VM.&lt;br /&gt;
==== Blocage des IP dans Haproxy ====&lt;br /&gt;
Créez les IP allowed dans la configuration Haproxy en ajoutant, dans le {{var|frontend front_web}} et avant les autres acl, l&#039;instruction suivante :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;        acl allowed_ajlsm src xx.xx.xx.xx xx.xx.xx.xx xx.xx.xx.xx/xx&lt;br /&gt;
        acl allowed_xx_client src xx.xx.xx.xx&lt;br /&gt;
&lt;br /&gt;
(Par exemple, pour les IP AJLSM et le client ad53)&lt;br /&gt;
&lt;br /&gt;
        acl allowed_ajlsm src 82.65.94.250 109.190.129.96 91.174.149.42 10.0.0.0/24&lt;br /&gt;
        acl allowed_ad53_client src 85.115.60.201&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==== Association des règles aux acl du client ====&lt;br /&gt;
Enfin, modifier les acl des domaines qui utilisent ces règles de blocage d&#039;IP en ajoutant l&#039;instruction suivante :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;        http-request deny                                         if      host_[le-host] !allowed_ajlsm !allowed_xx_client&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Par exemple :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;        acl host_salledelecturearchiveslamayenne  hdr(host)       -i      salle-de-lecture-archives.lamayenne.fr&lt;br /&gt;
        use_backend back_salledelecturearchiveslamayenne          if      host_salledelecturearchiveslamayenne&lt;br /&gt;
        http-request deny                                         if      host_salledelecturearchiveslamayenne !allowed_ajlsm !allowed_ad53_client&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==== Forcer le HTTPS sur un domaine ====&lt;br /&gt;
On souhaite que le WAF prenne bien en compte l&#039;acl pour un domaine avec SSL.&lt;br /&gt;
&lt;br /&gt;
Ajouter la commande suivante dans l&#039;acl concerné.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;http-request redirect scheme https                      if          { hdr(Host) -i [le-domaine] } !{ ssl_fc }&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Par exemple, pour ad53 :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;        acl host_ssl_archiveslamayenne  hdr(host)               -i          archives.lamayenne.fr&lt;br /&gt;
        use_backend back_ssl_archiveslamayenne                  if          host_ssl_archiveslamayenne&lt;br /&gt;
        http-request redirect scheme https                      if          { hdr(Host) -i archives.lamayenne.fr } !{ ssl_fc }&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Vérifier la configuration haproxy avec la commande : &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;haproxy -f /etc/haproxy/haproxy.cfg -c -V&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modification de la configuration apache des domaines ==&lt;br /&gt;
Dans la configuration apache de chaque site, il faut ajouter les IP privées des 2 Haproxy.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;        RewriteCond %{REMOTE_ADDR} !10.0.0.30&lt;br /&gt;
        RewriteCond %{REMOTE_ADDR} !10.0.0.31&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Puis, commenter la ligne :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;#RewriteRule .* /403.html [R=403,L]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Modification des logs pour le suivi des utilisateurs ====&lt;br /&gt;
Lorsque l&#039;on bascule le flux vers le WAF, c&#039;est l&#039;IP de Haproxy qui est la seule à communiquer avec la VM.&lt;br /&gt;
&lt;br /&gt;
Pour avoir des statistiques du nombre d&#039;utilisateurs, il faut modifier les configuration apache et ajoutant les instructions suivantes (conserver la configuration hors WAF en cas de suppression du WAF) :&lt;br /&gt;
&lt;br /&gt;
Activer le module Apache remoteip :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;a2enmod remoteip&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Modifier la configuration Apache du site :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;       # Configuration des logs pour suivi par IP utilisateurs&lt;br /&gt;
        RemoteIPHeader X-Forwarded-For&lt;br /&gt;
        LogFormat &amp;quot;%a %l %u %t \&amp;quot;%r\&amp;quot; %&amp;gt;s %b \&amp;quot;%{Referer}i\&amp;quot; \&amp;quot;%{User-Agent}i\&amp;quot;&amp;quot; forwarded&lt;br /&gt;
&lt;br /&gt;
        ErrorLog /var/log/apache2/archives.lamayenne.fr.errors.log&lt;br /&gt;
        CustomLog /var/log/apache2/archives.lamayenne.fr.log forwarded&lt;br /&gt;
        # Fin configuration des logs pour suivi par IP utilisateurs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        #### Configuration log hors WAF &lt;br /&gt;
        #ErrorLog /var/log/apache2/archives.lamayenne.fr.errors.log&lt;br /&gt;
        #CustomLog /var/log/apache2/archives.lamayenne.fr.log combined&lt;br /&gt;
        #### Fin configuration log hors WAF&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Application des règles HaProxy ==&lt;br /&gt;
Une fois les modifications terminées, on applique la configuration en relançant le service.&lt;br /&gt;
=== Redémarrer HAPROXY ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;service haproxy restart&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Vérifier que le HAPROXY est en vie ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;service haproxy status&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Logrotate Haproxy ===&lt;br /&gt;
Le logrotate est configuré et fait une rotation journalière (configuration dans {{path|/etc/logrotate.d/haproxy}}),&lt;br /&gt;
Il y a un palier maximum de 500M par fichier de log (on peut adapter). &lt;br /&gt;
&lt;br /&gt;
Le log est compressé (en .1, .2.gz ...) soit lorsqu&#039;il atteint 500M, soit au terme de la journée.&lt;br /&gt;
Les plus anciens logs compressés sont supprimés graduellement et automatiquement.&lt;br /&gt;
&lt;br /&gt;
La conf est la suivante :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;/var/log/haproxy.log {&lt;br /&gt;
   daily&lt;br /&gt;
   rotate 15&lt;br /&gt;
   maxsize 500M&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Problèmes et solutions ==&lt;br /&gt;
En cas d&#039;erreur de configuration, on peut sortir un état plus détaillé du service haproxy avec la commande :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;$ sudo systemctl status haproxy.service -l --no-pager&lt;br /&gt;
● haproxy.service - HAProxy Load Balancer&lt;br /&gt;
     Loaded: loaded (/lib/systemd/system/haproxy.service; enabled; vendor preset: enabled)&lt;br /&gt;
     Active: active (running) since Thu 2022-05-19 10:36:36 UTC; 9s ago&lt;br /&gt;
       Docs: man:haproxy(1)&lt;br /&gt;
             file:/usr/share/doc/haproxy/configuration.txt.gz&lt;br /&gt;
    Process: 88895 ExecStartPre=/usr/sbin/haproxy -f $CONFIG -c -q $EXTRAOPTS (code=exited, status=0/SUCCESS)&lt;br /&gt;
   Main PID: 88906 (haproxy)&lt;br /&gt;
      Tasks: 5 (limit: 9327)&lt;br /&gt;
     Memory: 9.4M&lt;br /&gt;
     CGroup: /system.slice/haproxy.service&lt;br /&gt;
             ├─88906 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -S /run/haproxy-master.sock&lt;br /&gt;
             └─88916 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -S /run/haproxy-master.sock&lt;br /&gt;
&lt;br /&gt;
May 19 10:36:36 haproxy-01 haproxy[88906]: Proxy back_ad53goaccess started.&lt;br /&gt;
May 19 10:36:36 haproxy-01 haproxy[88906]: Proxy back_ad53goaccess started.&lt;br /&gt;
May 19 10:36:36 haproxy-01 haproxy[88906]: Proxy back_salledelecturearchiveslamayenne started.&lt;br /&gt;
May 19 10:36:36 haproxy-01 haproxy[88906]: Proxy back_salledelecturearchiveslamayenne started.&lt;br /&gt;
May 19 10:36:36 haproxy-01 haproxy[88906]: Proxy back_ad53internetpublicationajlsm started.&lt;br /&gt;
May 19 10:36:36 haproxy-01 haproxy[88906]: Proxy back_ad53internetpublicationajlsm started.&lt;br /&gt;
May 19 10:36:36 haproxy-01 haproxy[88906]: Proxy back_ad53preprodajlsm started.&lt;br /&gt;
May 19 10:36:36 haproxy-01 haproxy[88906]: Proxy back_ad53preprodajlsm started.&lt;br /&gt;
May 19 10:36:36 haproxy-01 haproxy[88906]: Proxy back_ad53slecturepublicationajlsm started.&lt;br /&gt;
May 19 10:36:36 haproxy-01 haproxy[88906]: Proxy back_ad53slecturepublicationajlsm started.&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
== Tester un domaine en passant par le reverse proxy HAPROXY == &lt;br /&gt;
(sans avoir à faire une migration PROD / sans impact CLIENT).&lt;br /&gt;
&lt;br /&gt;
Les tests sont lancés depuis votre poste de travail en suivant les instructions ci-dessous.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Exemple : Tests sur la VM Port Dunkerque&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Rajouter cette ligne dans le fichier hosts du poste de travail d&#039;où seront lancés les tests :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;51.83.117.120 port-dunkerque.pleade.com&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{remarque|Pour info, cette IP 51.83.117.120 pointe sur l&#039;IP redondée du HAPROXY soit 10.0.0.32.}}&lt;br /&gt;
Il faut bien tester pour détecter d&#039;éventuels faux positifs (logs : {{path|/var/log/haproxy.log}})&lt;br /&gt;
== Réplication de la configuration dans les 2 Haproxy ==&lt;br /&gt;
Une fois la configuration {{path|/etc/haproxy/haproxy.cfg}} testée et validée dans le Haproxy01, répliquez cette configuration dans Haproxy02.&lt;br /&gt;
== Ansible ==&lt;br /&gt;
=== Réplication avec ansile ===&lt;br /&gt;
{{important|Source V1 pour l&#039;ansibelisation du déploiement Haproxy dans le SVN sous le nom : {{path|ansible-ajlsm/trunk/ansible-ajlsm-haproxy}}.&lt;br /&gt;
&lt;br /&gt;
Après chaque modification, pensez à commiter !!!}}&lt;br /&gt;
&lt;br /&gt;
{{notice|Ne pas oublier de changer les mots de passes dans inventory/ajlsm_loadbalancer.inventory (à terme il faudra utiliser des clés publiques ainsi qu&#039;Ansible-Vault)}}&lt;br /&gt;
==== Installation de Ansible ====&lt;br /&gt;
Il faut installer Ansible au préalable ( https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#installing-ansible-on-ubuntu )&lt;br /&gt;
==== Paramétrage de Ansible ====&lt;br /&gt;
#Ajouter la variable d&#039;environnement.&lt;br /&gt;
#Modifier les clés dans le fichier ansible-ajlsm-haproxy/inventory/ajlsm_loadbalancer.inventory&lt;br /&gt;
&lt;br /&gt;
==== Variabilisation ====&lt;br /&gt;
Par exemple, les IP pour le traitement des accès par IP et blocage, on variabilise la configuration dans Haproxy en ajoutant, Dans le fichier {{path|/ansible-ajlsm-haproxy/inventory/group_vars/ajlsm_loadbalancer/haproxy.yml}} et juste avant {{var|frontend front_web}} :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;---&lt;br /&gt;
haproxy_allowed_ips_ajlsm: &amp;quot; xx.xx.xx.xx xx.xx.xx.xx xx.xx.xx.xx/xx&amp;quot;&lt;br /&gt;
haproxy_allowed_ips_[le-client]_client: &amp;quot;xx.xx.xx.xx&amp;quot;&lt;br /&gt;
haproxy_custom_configuration: |&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Puis en ajoutant, dans le frontend front_web et avant les autres acl, l&#039;instruction suivante :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;        acl allowed_ajlsm src {{ haproxy_allowed_ips_ajlsm }}&lt;br /&gt;
        acl allowed_[le-client]_client src {{ haproxy_allowed_ips_[le-client]_client }}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Par exemple, pour AJLSM et ad53 :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;---&lt;br /&gt;
haproxy_allowed_ips_ajlsm: &amp;quot;82.65.94.250 109.190.129.96 91.174.149.42 10.0.0.0/24&amp;quot;&lt;br /&gt;
haproxy_allowed_ips_ad53_client: &amp;quot;85.115.60.201&amp;quot;&lt;br /&gt;
haproxy_custom_configuration: |&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
        acl allowed_ajlsm src {{ haproxy_allowed_ips_ajlsm }}&lt;br /&gt;
        acl allowed_ad53_client src {{ haproxy_allowed_ips_ad53_client }}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==== Réplication ====&lt;br /&gt;
#Il faut être sous VPN. &lt;br /&gt;
#Dans {{path|/etc/host}}, ajouter les 2 hosts : 10.0.0.30	haproxy01.ajlsm.lan, et : 10.0.0.31	haproxy02.ajlsm.lan&lt;br /&gt;
#Après avoir testé la configuration dans Haproxy01, créer le fichier Haproxy.yml (copie du fichier Haproxy01 en retirant les sections &amp;quot;global&amp;quot; et &amp;quot;default&amp;quot;) et ajoutant les variables, si nécessaire.&lt;br /&gt;
#Le fichier Haproxy.yml doit être placé dans le répertoire {{path|/ansible-ajlsm-haproxy/inventory/group_vars/ajlsm_loadbalancer/haproxy.yml}}&lt;br /&gt;
#Lancer la commande depuis la racine du dossier décompressé (il faut avoir ansible.cfg en visu lorqu&#039;on fait un ls).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;ansible-playbook ./plays/deploy.haproxy.yml -l ajlsm_loadbalancer&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{notice|Il faut un environnement python. Penser à lancer &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;source .venv/bin/activate&amp;lt;/syntaxhighlight&amp;gt; si vous travaillez dans un environnement spécifique}}&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;source .venv/bin/activate &amp;amp;&amp;amp; ansible-playbook ./plays/deploy.haproxy.yml -l ajlsm_loadbalancer&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Si tout va bien :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;ansible-ajlsm-haproxy ~$ ansible-playbook ./plays/deploy.haproxy.yml -l ajlsm_loadbalancer&lt;br /&gt;
&lt;br /&gt;
PLAY [ajlsm_loadbalancer] ****************************************************************************************************************************************************************************************************************&lt;br /&gt;
&lt;br /&gt;
TASK [Gathering Facts] *******************************************************************************************************************************************************************************************************************&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [haproxy : Install packages] ********************************************************************************************************************************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [haproxy : Deploy configuration and validate it] ************************************************************************************************************************************************************************************&lt;br /&gt;
changed: [haproxy02.ajlsm.lan]&lt;br /&gt;
changed: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [haproxy : Restore configuration (validation failed)] *******************************************************************************************************************************************************************************&lt;br /&gt;
skipping: [haproxy01.ajlsm.lan]&lt;br /&gt;
skipping: [haproxy02.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [haproxy : Remove restored backup file] *********************************************************************************************************************************************************************************************&lt;br /&gt;
skipping: [haproxy01.ajlsm.lan]&lt;br /&gt;
skipping: [haproxy02.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [haproxy : Start service and enable it on boot] *************************************************************************************************************************************************************************************&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [haproxy : Failure] *****************************************************************************************************************************************************************************************************************&lt;br /&gt;
skipping: [haproxy01.ajlsm.lan]&lt;br /&gt;
skipping: [haproxy02.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
RUNNING HANDLER [haproxy : restart haproxy] **********************************************************************************************************************************************************************************************&lt;br /&gt;
changed: [haproxy02.ajlsm.lan]&lt;br /&gt;
changed: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
PLAY RECAP *******************************************************************************************************************************************************************************************************************************&lt;br /&gt;
haproxy01.ajlsm.lan        : ok=5    changed=2    unreachable=0    failed=0    skipped=3    rescued=0    ignored=0   &lt;br /&gt;
haproxy02.ajlsm.lan        : ok=5    changed=2    unreachable=0    failed=0    skipped=3    rescued=0    ignored=0   &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== En cas d&#039;erreur après le lancement de la commande ==== &lt;br /&gt;
===== Essayer la commande ===== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;ANSIBLE_CONFIG=ansible.cfg ansible-playbook ./plays/deploy.haproxy.yml -l ajlsm_loadbalancer&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette partie est à compléter selon l&#039;évolution du script de déploiement.&lt;br /&gt;
===== 1 - Si la commande renvoie : =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;-bash: ansible-playbook: command not found&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Voir tuto : https://stackoverflow.com/questions/63177609/zsh-command-not-found-ansible-after-pip-installing&lt;br /&gt;
===== 2 - Si la commande renvoie : =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;ansible-playbook ./plays/deploy.haproxy.yml -l ajlsm_loadbalancer&lt;br /&gt;
&lt;br /&gt;
PLAY [ajlsm_loadbalancer] *****************************************************************************************************************************************************************************************************************************&lt;br /&gt;
&lt;br /&gt;
TASK [Gathering Facts] ********************************************************************************************************************************************************************************************************************************&lt;br /&gt;
fatal: [haproxy01.ajlsm.lan]: UNREACHABLE! =&amp;gt; {&amp;quot;changed&amp;quot;: false, &amp;quot;msg&amp;quot;: &amp;quot;Failed to connect to the host via ssh: ssh: Could not resolve hostname haproxy01.ajlsm.lan: nodename nor servname provided, or not known&amp;quot;, &amp;quot;unreachable&amp;quot;: true}&lt;br /&gt;
fatal: [haproxy02.ajlsm.lan]: UNREACHABLE! =&amp;gt; {&amp;quot;changed&amp;quot;: false, &amp;quot;msg&amp;quot;: &amp;quot;Failed to connect to the host via ssh: ssh: Could not resolve hostname haproxy02.ajlsm.lan: nodename nor servname provided, or not known&amp;quot;, &amp;quot;unreachable&amp;quot;: true}&lt;br /&gt;
&lt;br /&gt;
PLAY RECAP ********************************************************************************************************************************************************************************************************************************************&lt;br /&gt;
haproxy01.ajlsm.lan        : ok=0    changed=0    unreachable=1    failed=0    skipped=0    rescued=0    ignored=0   &lt;br /&gt;
haproxy02.ajlsm.lan        : ok=0    changed=0    unreachable=1    failed=0    skipped=0    rescued=0    ignored=0&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dans {{path|/etc/host}}, ajouter les 2 hosts : &lt;br /&gt;
#10.0.0.30 haproxy01.ajlsm.lan&lt;br /&gt;
#10.0.0.31 haproxy02.ajlsm.lan&lt;br /&gt;
&lt;br /&gt;
==== Reste à faire ====&lt;br /&gt;
Fine-tuning pour une maintenance simplifiée + le vault&amp;amp;clé publique pour la sécurité des mots de passes&lt;br /&gt;
# Il faudrait vaulter des choses,  &lt;br /&gt;
# améliorer le playbook &amp;amp; le rôle  &lt;br /&gt;
# ainsi que variabiliser plus de choses;&lt;br /&gt;
&lt;br /&gt;
== Migrer un site vers HAPROXY (mise en production) == &lt;br /&gt;
(après avoir testé)&lt;br /&gt;
&lt;br /&gt;
* Soit changer le DNS vers 51.83.117.120 (le client doit faire pointer son DNS sur cette IP)&lt;br /&gt;
* Soit aller dans les NAT One-to-One (1:1) d&#039;OPNSENSE, et changer l&#039;IP du client vers 10.0.0.32 (sur la correspondance IP externe client &amp;lt;-&amp;gt; IP interne client de la page)&lt;br /&gt;
Lors d&#039;une mise en production, pour éviter faire changer aux clients le DNS tout de suite et pour garder un débrayage facile : depuis le pare-feu OPNSense -&amp;gt; firewall -&amp;gt; NAT -&amp;gt; one-to-one, on fait pointer l&#039;IP initiale de la VM vers 10.0.0.32. &lt;br /&gt;
&lt;br /&gt;
Dans l&#039;exemple pour PORT DUNKERQUE, ça voudrait dire faire pointer 46.105.188.170 sur 10.0.0.32 au lieu de 10.0.0.24.&lt;br /&gt;
&lt;br /&gt;
Voir la copie d&#039;écran de OPNSense : [[media:Nat.png]]&lt;br /&gt;
&lt;br /&gt;
== Arrêter le WAF ==&lt;br /&gt;
En cas de problème avec une VM client (un blocage, ralentissement, faux positifs, etc.)&lt;br /&gt;
* Modifier les configuration apache en décommentant &amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;#RewriteRule .* /403.html [R,L]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
et en remettant les règles pour les logs (commenter la section et décommenter l&#039;autre) :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;       # Configuration des logs pour suivi par IP utilisateurs&lt;br /&gt;
        #RemoteIPHeader X-Forwarded-For&lt;br /&gt;
        #LogFormat &amp;quot;%a %l %u %t \&amp;quot;%r\&amp;quot; %&amp;gt;s %b \&amp;quot;%{Referer}i\&amp;quot; \&amp;quot;%{User-Agent}i\&amp;quot;&amp;quot; forwarded&lt;br /&gt;
&lt;br /&gt;
        #ErrorLog /var/log/apache2/chercher-archives.lamayenne.fr.errors.log&lt;br /&gt;
        #CustomLog /var/log/apache2/chercher-archives.lamayenne.fr.log forwarded&lt;br /&gt;
        # Fin configuration des logs pour suivi par IP utilisateurs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        #### Configuration log hors WAF &lt;br /&gt;
        ErrorLog /var/log/apache2/archives.lamayenne.fr.errors.log&lt;br /&gt;
        CustomLog /var/log/apache2/archives.lamayenne.fr.log combined&lt;br /&gt;
        #### Fin configuration log hors WAF &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Remettre l&#039;IP interne du client (et pas celle du HAPROXY) dans le NAT 1:1 d&#039;OPNSENSE. &lt;br /&gt;
* Ou bien, éteindre les deux machines VM modsec-spoe (Proxmox Saturne) pour désactiver le WAF de force.&lt;br /&gt;
== Faux positifs ==&lt;br /&gt;
On parle de &amp;quot;faux positif &amp;quot; lorsque un paquet anodin (ne constituant aucune menace réelle) est détecté comme tentative d&#039;intrusion.&lt;br /&gt;
&lt;br /&gt;
On parle de &amp;quot;faux négatif&amp;quot; lorsqu&#039;une tentative d&#039;intrusion n&#039;est pas détectée.&lt;br /&gt;
&lt;br /&gt;
{{important|En attente de la nouvelle documentation de Coraza}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Gestion d&#039;un faux positif Coraza (OWASP CRS) sur Archives de la Mayenne =&lt;br /&gt;
&lt;br /&gt;
== Contexte ==&lt;br /&gt;
&lt;br /&gt;
L&#039;application Archives de la Mayenne (Drupal + Pleade/Lucene) générait une erreur HTTP 403 sur certaines recherches contenant :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Saint-Vénérand (Laval)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le WAF Coraza détectait à tort une tentative d&#039;injection SQL car la chaîne :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Vénérand (&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
contient le motif :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
rand (&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
qui correspond à une signature SQL de la règle OWASP CRS 942151.&lt;br /&gt;
&lt;br /&gt;
== Identification du faux positif ==&lt;br /&gt;
&lt;br /&gt;
Recherche dans les logs Coraza :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
tail -f /var/log/coraza-spoa/coraza-agent.log&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Extrait du log :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;rule_id&amp;quot;:942151,&lt;br /&gt;
  &amp;quot;msg&amp;quot;:&amp;quot;SQL Injection Attack: SQL function name detected&amp;quot;,&lt;br /&gt;
  &amp;quot;data&amp;quot;:&amp;quot;Matched Data: rand ( found within ARGS:fquery1: Saint-Vénérand (Laval)&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La règle responsable est :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
942151 - SQL Injection Attack: SQL function name detected&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Localisation de la configuration Coraza ==&lt;br /&gt;
&lt;br /&gt;
Service :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl status coraza-spoa&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Configuration principale :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/etc/coraza-spoa/config.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Extrait :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
Include /etc/coraza-spoa/custom-rules/*.conf&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le fichier de règles est généré automatiquement par Ansible :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/etc/coraza-spoa/custom-rules/900-runtime-overrides.conf&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Localisation de la source Ansible ==&lt;br /&gt;
&lt;br /&gt;
Recherche de la variable :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
grep -R &amp;quot;coraza_spoa_custom_rules_request_body_exclusions&amp;quot; -n .&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
roles/coraza/templates/custom-rules.conf.j2&lt;br /&gt;
inventory/group_vars/ajlsm_loadbalancer/coraza.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Template générateur :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
roles/coraza/templates/custom-rules.conf.j2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variables du groupe load balancer :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
inventory/group_vars/ajlsm_loadbalancer/coraza.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Vérification de la prise en compte de la variable ==&lt;br /&gt;
&lt;br /&gt;
Contrôle de la variable vue par Ansible :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible -i inventory haproxy01.ajlsm.lan \&lt;br /&gt;
  -m debug \&lt;br /&gt;
  -a &#039;var=coraza_spoa_custom_rules_request_body_exclusions&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La nouvelle règle doit apparaître dans la sortie.&lt;br /&gt;
&lt;br /&gt;
== Ajout de l&#039;exception ==&lt;br /&gt;
&lt;br /&gt;
Modification du fichier :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
inventory/group_vars/ajlsm_loadbalancer/coraza.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ajout dans la section :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
coraza_spoa_custom_rules_request_body_exclusions:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Règle finale retenue :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
  - id: 123471&lt;br /&gt;
    variable: &amp;quot;REQUEST_FILENAME&amp;quot;&lt;br /&gt;
    operator: &amp;quot;@rx&amp;quot;&lt;br /&gt;
    pattern: &amp;quot;^/(archives-en-ligne|pleade)/.*results(\\.html|\\.ajax-html)$&amp;quot;&lt;br /&gt;
    actions: &amp;quot;nolog,pass,ctl:ruleRemoveTargetById=942151;ARGS:/^(?:query[0-9]+|fquery[0-9]+)$/&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette règle :&lt;br /&gt;
&lt;br /&gt;
* s&#039;applique aux pages de résultats Pleade ;&lt;br /&gt;
* couvre les pages HTML classiques et les appels AJAX ;&lt;br /&gt;
* retire la règle CRS 942151 ;&lt;br /&gt;
* uniquement pour le paramètre ARGS:fquery1 ;&lt;br /&gt;
* conserve toutes les autres protections CRS.&lt;br /&gt;
&lt;br /&gt;
Exemples d&#039;URLs couvertes :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/archives-en-ligne/custom-results.html&lt;br /&gt;
/archives-en-ligne/results.html&lt;br /&gt;
/archives-en-ligne/functions/ead/custom-results.ajax-html&lt;br /&gt;
/pleade/custom-results.html&lt;br /&gt;
/pleade/functions/ead/custom-results.ajax-html&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ainsi que les motifs suivants :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
ARGS:query1&lt;br /&gt;
ARGS:query2&lt;br /&gt;
ARGS:query3&lt;br /&gt;
ARGS:fquery1&lt;br /&gt;
ARGS:fquery2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Vérification du rendu du template ==&lt;br /&gt;
&lt;br /&gt;
Simulation du déploiement :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook \&lt;br /&gt;
  -i inventory \&lt;br /&gt;
  ./plays/deploy.coraza.yml \&lt;br /&gt;
  --limit haproxy01.ajlsm.lan \&lt;br /&gt;
  --check \&lt;br /&gt;
  --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le diff doit montrer :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;apache&amp;quot;&amp;gt;&lt;br /&gt;
SecRule REQUEST_FILENAME &amp;quot;@rx ^/(archives-en-ligne|pleade)/.*results(\.html|\.ajax-html)$&amp;quot; \&lt;br /&gt;
  &amp;quot;id:123471,phase:1,nolog,pass,ctl:ruleRemoveTargetById=942151;ARGS:/^(?:query[0-9]+|fquery[0-9]+)$/&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Déploiement ==&lt;br /&gt;
&lt;br /&gt;
Attention : le rôle Coraza est indépendant du rôle HAProxy.&lt;br /&gt;
&lt;br /&gt;
Le playbook HAProxy :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
plays/deploy.haproxy.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ne déploie pas les règles Coraza.&lt;br /&gt;
&lt;br /&gt;
Le playbook Coraza est :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
plays/deploy.coraza.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Déploiement sur tous les load balancers :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook \&lt;br /&gt;
  -i inventory \&lt;br /&gt;
  ./plays/deploy.coraza.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer \&lt;br /&gt;
  --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Déploiement uniquement sur haproxy01 :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook \&lt;br /&gt;
  -i inventory \&lt;br /&gt;
  ./plays/deploy.coraza.yml \&lt;br /&gt;
  --limit haproxy01.ajlsm.lan \&lt;br /&gt;
  --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Déploiement uniquement sur haproxy02 :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook \&lt;br /&gt;
  -i inventory \&lt;br /&gt;
  ./plays/deploy.coraza.yml \&lt;br /&gt;
  --limit haproxy02.ajlsm.lan \&lt;br /&gt;
  --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Vérifications après déploiement ==&lt;br /&gt;
&lt;br /&gt;
Contrôle de la présence de la règle :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
grep -R &amp;quot;123471\|942151&amp;quot; /etc/coraza-spoa/custom-rules -n&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat attendu :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/etc/coraza-spoa/custom-rules/900-runtime-overrides.conf:&lt;br /&gt;
SecRule REQUEST_FILENAME &amp;quot;@rx ^/(archives-en-ligne|pleade)/.*results(\.html|\.ajax-html)$&amp;quot; \&lt;br /&gt;
&amp;quot;id:123471,...ctl:ruleRemoveTargetById=942151;ARGS:fquery1&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Contrôle du service :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl status coraza-spoa&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérification via Ansible :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible -i inventory ajlsm_loadbalancer \&lt;br /&gt;
  -m shell \&lt;br /&gt;
  -a &#039;grep -R &amp;quot;123471\|942151&amp;quot; /etc/coraza-spoa/custom-rules -n &amp;amp;&amp;amp; systemctl is-active coraza-spoa&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Validation fonctionnelle ==&lt;br /&gt;
&lt;br /&gt;
Tester la recherche :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Saint-Vénérand (Laval)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;URL principale ne doit plus renvoyer de 403 :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/archives-en-ligne/custom-results.html&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les appels AJAX associés ne doivent plus être bloqués :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/archives-en-ligne/functions/ead/custom-results.ajax-html&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les logs Coraza ne doivent plus contenir de déclenchement de la règle 942151 pour le paramètre :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
ARGS:fquery1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Points importants ==&lt;br /&gt;
&lt;br /&gt;
* Les règles Coraza sont gérées par Ansible.&lt;br /&gt;
* Toute modification manuelle dans /etc/coraza-spoa/custom-rules/ sera écrasée lors d&#039;un prochain déploiement.&lt;br /&gt;
* La source de vérité est :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
inventory/group_vars/ajlsm_loadbalancer/coraza.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Les déploiements de configuration HAProxy et Coraza sont indépendants.&lt;br /&gt;
* Une modification des règles Coraza nécessite l&#039;exécution du playbook :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
plays/deploy.coraza.yml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sur le poste local, dans le répertoire ansible-ajlsm, lancez :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.coraza.yml --limit ajlsm_loadbalancer --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.coraza.yml --limit ajlsm_loadbalancer --diff&lt;br /&gt;
&lt;br /&gt;
PLAY [Deploy Coraza SPOA WAF] ***************************************************************************************************************************&lt;br /&gt;
&lt;br /&gt;
TASK [Gathering Facts] **********************************************************************************************************************************&lt;br /&gt;
[WARNING]: Host &#039;haproxy02.ajlsm.lan&#039; is using the discovered Python interpreter at &#039;/usr/bin/python3.10&#039;, but future installation of another Python interpreter could cause a different interpreter to be discovered. See https://docs.ansible.com/ansible-core/2.20/reference_appendices/interpreter_discovery.html for more information.&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
[WARNING]: Host &#039;haproxy01.ajlsm.lan&#039; is using the discovered Python interpreter at &#039;/usr/bin/python3.10&#039;, but future installation of another Python interpreter could cause a different interpreter to be discovered. See https://docs.ansible.com/ansible-core/2.20/reference_appendices/interpreter_discovery.html for more information.&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Install build dependencies] **************************************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Install Go via snap] *********************************************************************************************************************&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Create build directory] ******************************************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Clone coraza-spoa repository] ************************************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Check if coraza-spoa binary already exists] **********************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Build coraza-spoa] ***********************************************************************************************************************&lt;br /&gt;
skipping: [haproxy01.ajlsm.lan]&lt;br /&gt;
skipping: [haproxy02.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Install coraza-spoa binary] **************************************************************************************************************&lt;br /&gt;
skipping: [haproxy01.ajlsm.lan]&lt;br /&gt;
skipping: [haproxy02.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Create coraza-spoa group] ****************************************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Create coraza-spoa user] *****************************************************************************************************************&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Create configuration directory] **********************************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Create log directories] ******************************************************************************************************************&lt;br /&gt;
ok: [haproxy01.ajlsm.lan] =&amp;gt; (item=/var/log/coraza-spoa)&lt;br /&gt;
ok: [haproxy02.ajlsm.lan] =&amp;gt; (item=/var/log/coraza-spoa)&lt;br /&gt;
ok: [haproxy02.ajlsm.lan] =&amp;gt; (item=/var/log/coraza-spoa/audit)&lt;br /&gt;
ok: [haproxy01.ajlsm.lan] =&amp;gt; (item=/var/log/coraza-spoa/audit)&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Create log files] ************************************************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan] =&amp;gt; (item=server.log)&lt;br /&gt;
ok: [haproxy01.ajlsm.lan] =&amp;gt; (item=server.log)&lt;br /&gt;
ok: [haproxy01.ajlsm.lan] =&amp;gt; (item=error.log)&lt;br /&gt;
ok: [haproxy02.ajlsm.lan] =&amp;gt; (item=error.log)&lt;br /&gt;
ok: [haproxy01.ajlsm.lan] =&amp;gt; (item=audit.log)&lt;br /&gt;
ok: [haproxy02.ajlsm.lan] =&amp;gt; (item=audit.log)&lt;br /&gt;
ok: [haproxy01.ajlsm.lan] =&amp;gt; (item=debug.log)&lt;br /&gt;
ok: [haproxy02.ajlsm.lan] =&amp;gt; (item=debug.log)&lt;br /&gt;
ok: [haproxy01.ajlsm.lan] =&amp;gt; (item=coraza-agent.log)&lt;br /&gt;
ok: [haproxy02.ajlsm.lan] =&amp;gt; (item=coraza-agent.log)&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Create rollback backup directory] ********************************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Deploy coraza.cfg for HAProxy] ***********************************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Check if current coraza-spoa config exists] **********************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Check if current custom rules file exists] ***********************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Backup current coraza-spoa config] *******************************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Backup current custom rules file] ********************************************************************************************************&lt;br /&gt;
changed: [haproxy01.ajlsm.lan]&lt;br /&gt;
changed: [haproxy02.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Deploy coraza-spoa config.yaml] **********************************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Create custom rules directory] ***********************************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Deploy custom rules] *********************************************************************************************************************&lt;br /&gt;
--- before: /etc/coraza-spoa/custom-rules/900-runtime-overrides.conf&lt;br /&gt;
+++ after: /Users/jlarvers/.ansible/tmp/ansible-local-20994a3e3jiy7/tmp2vqgd1ck/custom-rules.conf.j2&lt;br /&gt;
@@ -47,7 +47,7 @@&lt;br /&gt;
 SecRule REQUEST_FILENAME &amp;quot;@rx /full_html?&amp;quot; \&lt;br /&gt;
   &amp;quot;id:123470,phase:1,nolog,pass,ctl:requestBodyAccess=Off&amp;quot;&lt;br /&gt;
 SecRule REQUEST_FILENAME &amp;quot;@rx ^/(archives-en-ligne|pleade)/.*results(\.html|\.ajax-html)$&amp;quot; \&lt;br /&gt;
-  &amp;quot;id:123471,phase:1,nolog,pass,ctl:ruleRemoveTargetById=942151;ARGS:fquery1&amp;quot;&lt;br /&gt;
+  &amp;quot;id:123471,phase:1,nolog,pass,ctl:ruleRemoveTargetById=942151;ARGS:/^(?:query[0-9]+|fquery[0-9]+)$/&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 SecRequestBodyLimit 524288000&lt;br /&gt;
 SecRequestBodyNoFilesLimit 524288000&lt;br /&gt;
&lt;br /&gt;
changed: [haproxy02.ajlsm.lan]&lt;br /&gt;
--- before: /etc/coraza-spoa/custom-rules/900-runtime-overrides.conf&lt;br /&gt;
+++ after: /Users/jlarvers/.ansible/tmp/ansible-local-20994a3e3jiy7/tmpd0a58h10/custom-rules.conf.j2&lt;br /&gt;
@@ -47,7 +47,7 @@&lt;br /&gt;
 SecRule REQUEST_FILENAME &amp;quot;@rx /full_html?&amp;quot; \&lt;br /&gt;
   &amp;quot;id:123470,phase:1,nolog,pass,ctl:requestBodyAccess=Off&amp;quot;&lt;br /&gt;
 SecRule REQUEST_FILENAME &amp;quot;@rx ^/(archives-en-ligne|pleade)/.*results(\.html|\.ajax-html)$&amp;quot; \&lt;br /&gt;
-  &amp;quot;id:123471,phase:1,nolog,pass,ctl:ruleRemoveTargetById=942151;ARGS:fquery1&amp;quot;&lt;br /&gt;
+  &amp;quot;id:123471,phase:1,nolog,pass,ctl:ruleRemoveTargetById=942151;ARGS:/^(?:query[0-9]+|fquery[0-9]+)$/&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 SecRequestBodyLimit 524288000&lt;br /&gt;
 SecRequestBodyNoFilesLimit 524288000&lt;br /&gt;
&lt;br /&gt;
changed: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Remove legacy split custom rules files] **************************************************************************************************&lt;br /&gt;
ok: [haproxy01.ajlsm.lan] =&amp;gt; (item=900-legacy-overrides.conf)&lt;br /&gt;
ok: [haproxy02.ajlsm.lan] =&amp;gt; (item=900-legacy-overrides.conf)&lt;br /&gt;
ok: [haproxy01.ajlsm.lan] =&amp;gt; (item=900-exclusions.conf)&lt;br /&gt;
ok: [haproxy02.ajlsm.lan] =&amp;gt; (item=900-exclusions.conf)&lt;br /&gt;
ok: [haproxy01.ajlsm.lan] =&amp;gt; (item=910-crs-policy.conf)&lt;br /&gt;
ok: [haproxy02.ajlsm.lan] =&amp;gt; (item=910-crs-policy.conf)&lt;br /&gt;
ok: [haproxy01.ajlsm.lan] =&amp;gt; (item=920-body-limits.conf)&lt;br /&gt;
ok: [haproxy02.ajlsm.lan] =&amp;gt; (item=920-body-limits.conf)&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Validate coraza-spoa config and custom rules before restart] *****************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Deploy coraza-spoa systemd unit] *********************************************************************************************************&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
TASK [coraza : Enable and start coraza-spoa service] ****************************************************************************************************&lt;br /&gt;
ok: [haproxy01.ajlsm.lan]&lt;br /&gt;
ok: [haproxy02.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
RUNNING HANDLER [coraza : Restart coraza-spoa] **********************************************************************************************************&lt;br /&gt;
changed: [haproxy01.ajlsm.lan]&lt;br /&gt;
changed: [haproxy02.ajlsm.lan]&lt;br /&gt;
&lt;br /&gt;
PLAY RECAP **********************************************************************************************************************************************&lt;br /&gt;
haproxy01.ajlsm.lan        : ok=25   changed=3    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0   &lt;br /&gt;
haproxy02.ajlsm.lan        : ok=25   changed=3    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Les paramètres suivants puvent être utilisés avec ansible :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Option&lt;br /&gt;
! Description&lt;br /&gt;
! Modifie le serveur&lt;br /&gt;
! Affiche les différences&lt;br /&gt;
! Usage typique&lt;br /&gt;
|-&lt;br /&gt;
| aucune option&lt;br /&gt;
| Exécution normale du playbook&lt;br /&gt;
| Oui&lt;br /&gt;
| Non&lt;br /&gt;
| Déploiement standard&lt;br /&gt;
|-&lt;br /&gt;
| --check&lt;br /&gt;
| Simulation (dry-run)&lt;br /&gt;
| Non&lt;br /&gt;
| Non&lt;br /&gt;
| Vérifier ce qui serait modifié&lt;br /&gt;
|-&lt;br /&gt;
| --diff&lt;br /&gt;
| Exécution réelle avec affichage des différences&lt;br /&gt;
| Oui&lt;br /&gt;
| Oui&lt;br /&gt;
| Déployer en visualisant les changements&lt;br /&gt;
|-&lt;br /&gt;
| --check --diff&lt;br /&gt;
| Simulation avec affichage des différences&lt;br /&gt;
| Non&lt;br /&gt;
| Oui&lt;br /&gt;
| Vérifier précisément les modifications avant déploiement&lt;br /&gt;
|-&lt;br /&gt;
| --limit &amp;lt;hôte&amp;gt;&lt;br /&gt;
| Limite l&#039;exécution à un ou plusieurs hôtes&lt;br /&gt;
| Selon les autres options&lt;br /&gt;
| Selon les autres options&lt;br /&gt;
| Tester sur un seul serveur&lt;br /&gt;
|-&lt;br /&gt;
| --tags &amp;lt;tag&amp;gt;&lt;br /&gt;
| Exécute uniquement les tâches portant un tag donné&lt;br /&gt;
| Selon les autres options&lt;br /&gt;
| Selon les autres options&lt;br /&gt;
| Déployer uniquement un composant spécifique&lt;br /&gt;
|-&lt;br /&gt;
| --skip-tags &amp;lt;tag&amp;gt;&lt;br /&gt;
| Ignore les tâches portant un tag donné&lt;br /&gt;
| Selon les autres options&lt;br /&gt;
| Selon les autres options&lt;br /&gt;
| Exclure une partie du playbook&lt;br /&gt;
|-&lt;br /&gt;
| -v&lt;br /&gt;
| Mode verbeux&lt;br /&gt;
| Selon les autres options&lt;br /&gt;
| Selon les autres options&lt;br /&gt;
| Voir davantage d&#039;informations&lt;br /&gt;
|-&lt;br /&gt;
| -vv&lt;br /&gt;
| Mode très verbeux&lt;br /&gt;
| Selon les autres options&lt;br /&gt;
| Selon les autres options&lt;br /&gt;
| Débogage&lt;br /&gt;
|-&lt;br /&gt;
| -vvv&lt;br /&gt;
| Mode débogage avancé&lt;br /&gt;
| Selon les autres options&lt;br /&gt;
| Selon les autres options&lt;br /&gt;
| Analyse détaillée des connexions et modules&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Coraza =&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=S%C3%A9curit%C3%A9_PHP_%E2%80%93_CVE-2026-109618_/_CVE-2026-109619_%E2%80%93_Interventions_des_21_et_22_octobre_2026&amp;diff=6523</id>
		<title>Sécurité PHP – CVE-2026-109618 / CVE-2026-109619 – Interventions des 21 et 22 octobre 2026</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=S%C3%A9curit%C3%A9_PHP_%E2%80%93_CVE-2026-109618_/_CVE-2026-109619_%E2%80%93_Interventions_des_21_et_22_octobre_2026&amp;diff=6523"/>
		<updated>2026-10-22T15:11:52Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : /* 1.1. Tableau de suivi */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Sécurité PHP – CVE-2026-109618 / CVE-2026-109619 – Interventions des 21 et 22 octobre 2026 =&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Élément&lt;br /&gt;
! Information&lt;br /&gt;
|-&lt;br /&gt;
| Période&lt;br /&gt;
| 21 et 22 octobre 2026&lt;br /&gt;
|-&lt;br /&gt;
| Infrastructure&lt;br /&gt;
| AJLSM – Machines virtuelles, HAProxy et OPNsense&lt;br /&gt;
|-&lt;br /&gt;
| Objet&lt;br /&gt;
| Correction ou atténuation des vulnérabilités PHP et mises à jour des systèmes&lt;br /&gt;
|-&lt;br /&gt;
| Nature des travaux&lt;br /&gt;
| Maintenance de sécurité, contrôles applicatifs, haute disponibilité&lt;br /&gt;
|-&lt;br /&gt;
| État&lt;br /&gt;
| Partiellement terminé – maintenance OPNsense et systèmes anciens à poursuivre&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 1. Synthèse ultra-courte ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Bilan :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Les vulnérabilités PHP &#039;&#039;&#039;CVE-2026-109618&#039;&#039;&#039; et &#039;&#039;&#039;CVE-2026-109619&#039;&#039;&#039; ont été identifiées.&lt;br /&gt;
* Les VM utilisant des versions PHP corrigées ont été mises à jour lorsque les paquets étaient disponibles.&lt;br /&gt;
* Les VM utilisant d&#039;anciennes versions de PHP ont reçu une &#039;&#039;&#039;atténuation provisoire&#039;&#039;&#039; par désactivation de &amp;lt;code&amp;gt;session.upload_progress.enabled&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Les deux HAProxy ont été mis à jour ; leur fonctionnement Keepalived/VRRP a été corrigé et contrôlé.&lt;br /&gt;
* Les deux OPNsense ont reçu la même atténuation PHP provisoire.&lt;br /&gt;
* &#039;&#039;&#039;Les mises à jour complètes des deux OPNsense restent à effectuer.&#039;&#039;&#039;&lt;br /&gt;
* La version PHP 8.3.31 proposée par le dépôt OPNsense ne corrige pas les deux CVE selon FreeBSD VuXML.&lt;br /&gt;
* Les anciennes branches PHP devront faire l&#039;objet d&#039;un suivi particulier : l&#039;atténuation ne constitue pas un correctif définitif.&lt;br /&gt;
&lt;br /&gt;
=== 1.1. Tableau de suivi ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Machine&lt;br /&gt;
! VMID&lt;br /&gt;
! PHP / système&lt;br /&gt;
! Intervention&lt;br /&gt;
! État&lt;br /&gt;
|-&lt;br /&gt;
| TEMPLATE3&lt;br /&gt;
| 506&lt;br /&gt;
| Ubuntu 26.04.1 ; PHP 8.4.27 / 8.5.12&lt;br /&gt;
| Versions PHP corrigées ; contrôles et redémarrage&lt;br /&gt;
| Terminé&lt;br /&gt;
|-&lt;br /&gt;
| AD64&lt;br /&gt;
| 507&lt;br /&gt;
| Ubuntu 26.04.1 ; PHP 8.4.27 / 8.5.12&lt;br /&gt;
| Versions PHP corrigées ; contrôles et redémarrage&lt;br /&gt;
| Terminé&lt;br /&gt;
|-&lt;br /&gt;
| DEVTOOLS2 / pleade.com&lt;br /&gt;
| 508&lt;br /&gt;
| PHP 7.2&lt;br /&gt;
| Mise à jour disponible + atténuation provisoire&lt;br /&gt;
| Atténué ; PHP ancien&lt;br /&gt;
|-&lt;br /&gt;
| APBP2&lt;br /&gt;
| 510&lt;br /&gt;
| Ubuntu 26.04.1 ; PHP 8.4.27 / 8.5.12&lt;br /&gt;
| Versions PHP corrigées ; contrôles et redémarrage&lt;br /&gt;
| Terminé&lt;br /&gt;
|-&lt;br /&gt;
| DEVTOOLS&lt;br /&gt;
| 513&lt;br /&gt;
| PHP 5.6&lt;br /&gt;
| Atténuation provisoire&lt;br /&gt;
| PHP ancien – suivi nécessaire&lt;br /&gt;
|-&lt;br /&gt;
| ENCELADE&lt;br /&gt;
| 514&lt;br /&gt;
| PHP 7.4&lt;br /&gt;
| Atténuation provisoire&lt;br /&gt;
| PHP ancien – suivi nécessaire&lt;br /&gt;
|-&lt;br /&gt;
| MERCURE&lt;br /&gt;
| 515&lt;br /&gt;
| Ubuntu 20.04.6 ; PHP 7.2 / 7.4 / 8.0 / 8.1&lt;br /&gt;
| Atténuation provisoire sur les quatre branches&lt;br /&gt;
| Migration vers MERCURE3 à poursuivre&lt;br /&gt;
|-&lt;br /&gt;
| CENTREON-R8&lt;br /&gt;
| 520&lt;br /&gt;
| PHP 8.2.35&lt;br /&gt;
| Mise à jour PHP et contrôles Centreon&lt;br /&gt;
| PHP corrigé ; reboot noyau restant&lt;br /&gt;
|-&lt;br /&gt;
| AD53&lt;br /&gt;
| —&lt;br /&gt;
| PHP 7.2 / 7.3 / 8.0&lt;br /&gt;
| Atténuation provisoire dans les configurations PHP&lt;br /&gt;
| Atténué ; PHP ancien&lt;br /&gt;
|-&lt;br /&gt;
| HAProxy-01&lt;br /&gt;
| —&lt;br /&gt;
| Ubuntu 24.04 LTS&lt;br /&gt;
| Mise à jour OS, HAProxy et Keepalived&lt;br /&gt;
| Opérationnel&lt;br /&gt;
|-&lt;br /&gt;
| HAProxy-02&lt;br /&gt;
| —&lt;br /&gt;
| Ubuntu 24.04 LTS&lt;br /&gt;
| Mise à jour OS, HAProxy et Keepalived&lt;br /&gt;
| Opérationnel&lt;br /&gt;
|-&lt;br /&gt;
| SaturneFW1&lt;br /&gt;
| —&lt;br /&gt;
| OPNsense 26.1 ; PHP 8.3&lt;br /&gt;
| Atténuation PHP provisoire&lt;br /&gt;
| Mise à jour OPNsense restante&lt;br /&gt;
|-&lt;br /&gt;
| SaturneFW2&lt;br /&gt;
| —&lt;br /&gt;
| OPNsense 26.1.6 ; PHP 8.3.30&lt;br /&gt;
| Audit et atténuation PHP provisoire&lt;br /&gt;
| Mise à jour OPNsense restante&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; ce tableau reprend les machines dont les interventions ont été identifiées dans le suivi. Il ne constitue pas, à lui seul, un inventaire exhaustif de toutes les VM Proxmox.&lt;br /&gt;
&lt;br /&gt;
=== Machines à réintégrer au bilan des 21 et 22 octobre 2026 ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Machine&lt;br /&gt;
! Version PHP&lt;br /&gt;
! Intervention réalisée&lt;br /&gt;
! Vérifications restantes&lt;br /&gt;
|-&lt;br /&gt;
| Basse-Bretagne&lt;br /&gt;
| À retrouver dans les journaux d&#039;intervention&lt;br /&gt;
| Intervention du chantier de sécurité PHP à documenter&lt;br /&gt;
| Confirmer versions, correctifs et redémarrage éventuel&lt;br /&gt;
|-&lt;br /&gt;
| ENS Lyon&lt;br /&gt;
| À retrouver dans les journaux d&#039;intervention&lt;br /&gt;
| Intervention du chantier de sécurité PHP à documenter&lt;br /&gt;
| Confirmer versions, correctifs et redémarrage éventuel&lt;br /&gt;
|-&lt;br /&gt;
| APBP&lt;br /&gt;
| À retrouver dans les journaux d&#039;intervention&lt;br /&gt;
| Intervention du chantier de sécurité PHP à documenter&lt;br /&gt;
| Confirmer versions, correctifs et redémarrage éventuel&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; APBP et APBP2 sont deux machines distinctes. Les opérations effectuées sur APBP2 ne doivent pas être attribuées automatiquement à APBP.&lt;br /&gt;
&lt;br /&gt;
== 2. Origine de l&#039;intervention ==&lt;br /&gt;
&lt;br /&gt;
=== 2.1. Vulnérabilités PHP ===&lt;br /&gt;
&lt;br /&gt;
Deux vulnérabilités critiques ont motivé l&#039;intervention :&lt;br /&gt;
&lt;br /&gt;
* CVE-2026-109618&lt;br /&gt;
* CVE-2026-109619&lt;br /&gt;
&lt;br /&gt;
L&#039;avis FreeBSD VuXML publié le 21 octobre 2026 indique que ces vulnérabilités peuvent permettre une exécution de code à distance sans authentification, selon les conditions d&#039;exploitation.&lt;br /&gt;
&lt;br /&gt;
Référence :&lt;br /&gt;
&lt;br /&gt;
https://vuxml.FreeBSD.org/freebsd/d8e16d08-cd2f-11f1-8135-8447094a420f.html&lt;br /&gt;
&lt;br /&gt;
=== 2.2. Versions corrigées ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Branche PHP&lt;br /&gt;
! Première version corrigée&lt;br /&gt;
|-&lt;br /&gt;
| PHP 8.2&lt;br /&gt;
| 8.2.35&lt;br /&gt;
|-&lt;br /&gt;
| PHP 8.3&lt;br /&gt;
| 8.3.36&lt;br /&gt;
|-&lt;br /&gt;
| PHP 8.4&lt;br /&gt;
| 8.4.27&lt;br /&gt;
|-&lt;br /&gt;
| PHP 8.5&lt;br /&gt;
| 8.5.12&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les versions plus anciennes, notamment PHP 5.6, 7.2, 7.3, 7.4, 8.0 et 8.1, ne disposent pas d&#039;une version corrigée dans les branches officielles encore maintenues.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Conséquence :&#039;&#039;&#039; sur les serveurs anciens, la désactivation de la progression des téléversements PHP est une atténuation provisoire, et non une correction complète.&lt;br /&gt;
&lt;br /&gt;
== 3. Méthode de traitement ==&lt;br /&gt;
&lt;br /&gt;
Les interventions ont été organisées machine par machine :&lt;br /&gt;
&lt;br /&gt;
# Identifier la version de l&#039;OS.&lt;br /&gt;
# Identifier toutes les versions PHP installées.&lt;br /&gt;
# Déterminer les versions réellement utilisées par Apache ou PHP-FPM.&lt;br /&gt;
# Vérifier la disponibilité des mises à jour.&lt;br /&gt;
# Appliquer les correctifs PHP disponibles.&lt;br /&gt;
# Lorsque les correctifs ne sont pas disponibles, désactiver la progression des téléversements PHP.&lt;br /&gt;
# Redémarrer ou recharger les services concernés.&lt;br /&gt;
# Vérifier les versions PHP effectives.&lt;br /&gt;
# Contrôler le fonctionnement des applications.&lt;br /&gt;
# Identifier les redémarrages système encore nécessaires.&lt;br /&gt;
&lt;br /&gt;
=== 3.1. Commandes générales de diagnostic ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat /etc/os-release&lt;br /&gt;
&lt;br /&gt;
php -v&lt;br /&gt;
&lt;br /&gt;
php -i | grep -E \&lt;br /&gt;
  &#039;Loaded Configuration File|Scan this dir|session.upload_progress.enabled&#039;&lt;br /&gt;
&lt;br /&gt;
systemctl --type=service --state=running \&lt;br /&gt;
  | grep -Ei &#039;apache|php.*fpm&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sur Ubuntu :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt list --upgradable&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La disponibilité d&#039;un correctif ne doit pas être déduite uniquement du numéro de version PHP lorsque la distribution applique des correctifs rétroportés.&lt;br /&gt;
&lt;br /&gt;
== 4. Atténuation provisoire PHP ==&lt;br /&gt;
&lt;br /&gt;
=== 4.1. Principe ===&lt;br /&gt;
&lt;br /&gt;
La mesure retenue consiste à désactiver :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
session.upload_progress.enabled = Off&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Elle empêche PHP d&#039;utiliser le mécanisme de suivi de progression des téléversements.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Limites :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Elle réduit l&#039;exposition à certains chemins d&#039;exploitation.&lt;br /&gt;
* Elle ne corrige pas nécessairement les deux CVE.&lt;br /&gt;
* Elle ne remplace pas une mise à jour de sécurité.&lt;br /&gt;
* Elle doit être appliquée à toutes les configurations PHP réellement utilisées par le serveur Web.&lt;br /&gt;
* Une vérification en PHP CLI ne garantit pas, à elle seule, la configuration effective des processus Web.&lt;br /&gt;
&lt;br /&gt;
=== 4.2. Contrôle ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php -i | grep session.upload_progress.enabled&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat attendu :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
session.upload_progress.enabled =&amp;gt; Off =&amp;gt; Off&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sur les systèmes utilisant plusieurs versions PHP, chaque branche doit être contrôlée séparément.&lt;br /&gt;
&lt;br /&gt;
== 5. Interventions sur les machines virtuelles ==&lt;br /&gt;
&lt;br /&gt;
=== 5.1. TEMPLATE3 – VM 506 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Système :&#039;&#039;&#039; Ubuntu 26.04.1 LTS.&lt;br /&gt;
&lt;br /&gt;
Versions PHP présentes après intervention :&lt;br /&gt;
&lt;br /&gt;
* PHP 8.4.27&lt;br /&gt;
* PHP 8.5.12&lt;br /&gt;
&lt;br /&gt;
Ces versions correspondent aux premières versions corrigées identifiées dans l&#039;avis de sécurité.&lt;br /&gt;
&lt;br /&gt;
Contrôles effectués :&lt;br /&gt;
&lt;br /&gt;
* Versions PHP installées.&lt;br /&gt;
* Utilisation de PHP 8.4 par Apache.&lt;br /&gt;
* Vérification des configurations.&lt;br /&gt;
* Redémarrage de la VM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;État :&#039;&#039;&#039; intervention terminée pour les vulnérabilités PHP concernées.&lt;br /&gt;
&lt;br /&gt;
=== 5.2. AD64 – VM 507 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Système :&#039;&#039;&#039; Ubuntu 26.04.1 LTS.&lt;br /&gt;
&lt;br /&gt;
Versions PHP :&lt;br /&gt;
&lt;br /&gt;
* PHP 8.4.27&lt;br /&gt;
* PHP 8.5.12&lt;br /&gt;
&lt;br /&gt;
Interventions :&lt;br /&gt;
&lt;br /&gt;
* Mise à jour des versions PHP.&lt;br /&gt;
* Contrôle de la configuration Apache.&lt;br /&gt;
* Vérification de la version PHP utilisée par le serveur Web.&lt;br /&gt;
* Redémarrage de la VM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;État :&#039;&#039;&#039; versions PHP corrigées installées.&lt;br /&gt;
&lt;br /&gt;
Les contrôles fonctionnels Drupal/Pleade doivent rester intégrés à la validation des prochaines maintenances.&lt;br /&gt;
&lt;br /&gt;
=== 5.3. APBP2 – VM 510 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Système :&#039;&#039;&#039; Ubuntu 26.04.1 LTS.&lt;br /&gt;
&lt;br /&gt;
Versions PHP :&lt;br /&gt;
&lt;br /&gt;
* PHP 8.4.27&lt;br /&gt;
* PHP 8.5.12&lt;br /&gt;
&lt;br /&gt;
Interventions :&lt;br /&gt;
&lt;br /&gt;
* Mise à jour PHP.&lt;br /&gt;
* Vérification de la configuration Apache utilisant PHP 8.4.&lt;br /&gt;
* Contrôle des services.&lt;br /&gt;
* Redémarrage de la VM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;État :&#039;&#039;&#039; versions PHP corrigées installées.&lt;br /&gt;
&lt;br /&gt;
=== 5.4. DEVTOOLS2 / pleade.com – VM 508 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Version PHP :&#039;&#039;&#039; branche 7.2.&lt;br /&gt;
&lt;br /&gt;
Mise à jour constatée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
PHP 7.2 -&amp;gt; 7.2.24.17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La branche PHP 7.2 étant ancienne, cette mise à jour ne doit pas être assimilée à une correction définitive des deux CVE.&lt;br /&gt;
&lt;br /&gt;
Atténuation appliquée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
session.upload_progress.enabled = Off&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Contrôles réalisés :&lt;br /&gt;
&lt;br /&gt;
* Configuration PHP.&lt;br /&gt;
* Fonctionnement d&#039;Apache.&lt;br /&gt;
* Fonctionnement de Mantis.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;État :&#039;&#039;&#039; service fonctionnel avec atténuation provisoire.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;À faire :&#039;&#039;&#039; planifier le remplacement de PHP 7.2 par une branche maintenue, sous réserve de compatibilité applicative.&lt;br /&gt;
&lt;br /&gt;
=== 5.5. DEVTOOLS – VM 513 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Version PHP :&#039;&#039;&#039; PHP 5.6.&lt;br /&gt;
&lt;br /&gt;
Mesure appliquée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
session.upload_progress.enabled = Off&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;État :&#039;&#039;&#039; atténuation provisoire.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;À faire :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Identifier les dépendances applicatives à PHP 5.6.&lt;br /&gt;
* Préparer une migration vers une version PHP maintenue.&lt;br /&gt;
* Vérifier les autres mécanismes de réduction d&#039;exposition disponibles.&lt;br /&gt;
&lt;br /&gt;
=== 5.6. ENCELADE – VM 514 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Version PHP :&#039;&#039;&#039; PHP 7.4.&lt;br /&gt;
&lt;br /&gt;
Atténuation appliquée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
session.upload_progress.enabled = Off&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;État :&#039;&#039;&#039; atténuation provisoire.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;À faire :&#039;&#039;&#039; migration vers une version PHP maintenue ou remplacement de l&#039;environnement ancien.&lt;br /&gt;
&lt;br /&gt;
=== 5.7. MERCURE – VM 515 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Système :&#039;&#039;&#039; Ubuntu 20.04.6 LTS.&lt;br /&gt;
&lt;br /&gt;
Versions PHP-FPM identifiées :&lt;br /&gt;
&lt;br /&gt;
* PHP 7.2&lt;br /&gt;
* PHP 7.4&lt;br /&gt;
* PHP 8.0&lt;br /&gt;
* PHP 8.1&lt;br /&gt;
&lt;br /&gt;
La mesure provisoire a été appliquée aux quatre branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
session.upload_progress.enabled = Off&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Contrôles réalisés :&lt;br /&gt;
&lt;br /&gt;
* Services PHP-FPM actifs.&lt;br /&gt;
* Vérification des configurations.&lt;br /&gt;
* Contrôle HTTP : réponse 200.&lt;br /&gt;
* Vérification de l&#039;état applicatif.&lt;br /&gt;
&lt;br /&gt;
Aucune mise à jour de paquet n&#039;a été réalisée pendant cette intervention.&lt;br /&gt;
&lt;br /&gt;
Des extensions manquantes avaient également été relevées pour PHP 7.2, notamment concernant memcache et uploadprogress.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;État :&#039;&#039;&#039; atténuation appliquée ; applications accessibles.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Suite prévue :&#039;&#039;&#039; poursuivre la migration vers MERCURE3, plutôt que maintenir durablement cet environnement PHP ancien.&lt;br /&gt;
&lt;br /&gt;
=== 5.8. CENTREON-R8 – VM 520 ===&lt;br /&gt;
&lt;br /&gt;
Mise à jour PHP effectuée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
PHP 8.2.30 -&amp;gt; PHP 8.2.35&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Contrôles réalisés :&lt;br /&gt;
&lt;br /&gt;
* PHP-FPM 8.2.35 opérationnel.&lt;br /&gt;
* Extension SourceGuardian opérationnelle.&lt;br /&gt;
* Interface Centreon fonctionnelle.&lt;br /&gt;
* Métriques Centreon disponibles.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;État :&#039;&#039;&#039; PHP corrigé.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Reste à faire :&#039;&#039;&#039; redémarrage de la VM pour activer le noyau système mis à jour.&lt;br /&gt;
&lt;br /&gt;
=== 5.9. AD53 ===&lt;br /&gt;
&lt;br /&gt;
Versions PHP concernées :&lt;br /&gt;
&lt;br /&gt;
* PHP 7.2&lt;br /&gt;
* PHP 7.3&lt;br /&gt;
* PHP 8.0&lt;br /&gt;
&lt;br /&gt;
L&#039;intervention a porté sur &#039;&#039;&#039;11 fichiers php.ini&#039;&#039;&#039; correspondant aux différentes versions et aux différents contextes d&#039;exécution.&lt;br /&gt;
&lt;br /&gt;
Mesure appliquée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
session.upload_progress.enabled = Off&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Contrôles réalisés :&lt;br /&gt;
&lt;br /&gt;
* Vérification des configurations PHP.&lt;br /&gt;
* Redémarrage ou rechargement des services PHP-FPM concernés.&lt;br /&gt;
* Contrôle d&#039;Apache.&lt;br /&gt;
* Vérification du fonctionnement applicatif.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;État :&#039;&#039;&#039; atténuation provisoire appliquée.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; ces versions PHP restent anciennes. La désactivation de la progression des téléversements ne constitue pas une correction complète des vulnérabilités.&lt;br /&gt;
&lt;br /&gt;
== 6. HAProxy-01 et HAProxy-02 ==&lt;br /&gt;
&lt;br /&gt;
=== 6.1. Architecture ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Serveur&lt;br /&gt;
! Adresse&lt;br /&gt;
! Rôle&lt;br /&gt;
|-&lt;br /&gt;
| HAProxy-01&lt;br /&gt;
| 10.0.0.30&lt;br /&gt;
| MASTER nominal&lt;br /&gt;
|-&lt;br /&gt;
| HAProxy-02&lt;br /&gt;
| 10.0.0.31&lt;br /&gt;
| BACKUP nominal&lt;br /&gt;
|-&lt;br /&gt;
| VIP&lt;br /&gt;
| 10.0.0.32&lt;br /&gt;
| Adresse virtuelle Keepalived&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 6.2. Mises à jour ===&lt;br /&gt;
&lt;br /&gt;
Les deux serveurs ont été mis à jour vers un état Ubuntu 24.04 LTS cohérent.&lt;br /&gt;
&lt;br /&gt;
Versions vérifiées :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Ubuntu 24.04 LTS&lt;br /&gt;
Linux 6.8.0-147-generic&lt;br /&gt;
HAProxy 2.8.16&lt;br /&gt;
Keepalived 2.2.8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les mises à jour ont concerné environ 182 et 177 paquets selon les opérations examinées.&lt;br /&gt;
&lt;br /&gt;
Six paquets étaient temporairement retenus dans les résultats APT.&lt;br /&gt;
&lt;br /&gt;
Les services suivants ont été contrôlés :&lt;br /&gt;
&lt;br /&gt;
* HAProxy&lt;br /&gt;
* Keepalived&lt;br /&gt;
* systemd-networkd&lt;br /&gt;
&lt;br /&gt;
Aucun PHP installé par APT n&#039;a été identifié sur ces deux machines.&lt;br /&gt;
&lt;br /&gt;
=== 6.3. Incident Keepalived ===&lt;br /&gt;
&lt;br /&gt;
Pendant les mises à jour, des redémarrages de Keepalived ont provoqué des changements temporaires de rôle VRRP.&lt;br /&gt;
&lt;br /&gt;
Un problème de droits a également été identifié dans le script de contrôle HAProxy.&lt;br /&gt;
&lt;br /&gt;
Le script &amp;lt;code&amp;gt;chk_haproxy&amp;lt;/code&amp;gt; était exécuté sous un compte ne disposant pas des permissions nécessaires pour contrôler les processus HAProxy.&lt;br /&gt;
&lt;br /&gt;
Correction :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
user root&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette directive a été ajoutée dans le bloc &amp;lt;code&amp;gt;vrrp_script chk_haproxy&amp;lt;/code&amp;gt;, en conservant les autres paramètres existants.&lt;br /&gt;
&lt;br /&gt;
Priorités VRRP :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
HAProxy-01 : 103&lt;br /&gt;
HAProxy-02 : 102&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
État final :&lt;br /&gt;
&lt;br /&gt;
* HAProxy-01 : MASTER.&lt;br /&gt;
* HAProxy-02 : BACKUP.&lt;br /&gt;
* VIP présente sur HAProxy-01.&lt;br /&gt;
&lt;br /&gt;
=== 6.4. Test fonctionnel ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl --resolve archives.lamayenne.fr:443:10.0.0.32 \&lt;br /&gt;
  https://archives.lamayenne.fr/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
HTTP 200&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;État :&#039;&#039;&#039; fonctionnement confirmé pour le service testé.&lt;br /&gt;
&lt;br /&gt;
=== 6.5. Points restant à vérifier ===&lt;br /&gt;
&lt;br /&gt;
* Examiner les paquets APT retenus.&lt;br /&gt;
* Confirmer la stabilité de Keepalived lors des prochaines mises à jour.&lt;br /&gt;
* Refaire un test de bascule VRRP dans une fenêtre de maintenance.&lt;br /&gt;
* Vérifier la cohérence des configurations et certificats sur les deux HAProxy.&lt;br /&gt;
&lt;br /&gt;
Les certificats et certaines configurations sont déployés séparément sur HAProxy-01 et HAProxy-02 : leur synchronisation ne doit pas être présumée automatique.&lt;br /&gt;
&lt;br /&gt;
== 7. OPNsense – SaturneFW1 et SaturneFW2 ==&lt;br /&gt;
&lt;br /&gt;
=== 7.1. Architecture ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Pare-feu&lt;br /&gt;
! Adresse&lt;br /&gt;
! Fonction&lt;br /&gt;
|-&lt;br /&gt;
| SaturneFW1&lt;br /&gt;
| 10.0.0.2&lt;br /&gt;
| Principal&lt;br /&gt;
|-&lt;br /&gt;
| SaturneFW2&lt;br /&gt;
| 10.0.0.3&lt;br /&gt;
| Secondaire&lt;br /&gt;
|-&lt;br /&gt;
| Interface Web&lt;br /&gt;
| TCP 453&lt;br /&gt;
| Administration HTTPS&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
L&#039;accès distant d&#039;administration dépend notamment d&#039;un VPN OpenVPN hébergé sur FW1.&lt;br /&gt;
&lt;br /&gt;
Cette dépendance doit être prise en compte avant toute mise à jour ou redémarrage de FW1.&lt;br /&gt;
&lt;br /&gt;
=== 7.2. État des versions ===&lt;br /&gt;
&lt;br /&gt;
Sur FW2, les versions suivantes ont été constatées :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
OPNsense 26.1.6&lt;br /&gt;
FreeBSD 14 amd64&lt;br /&gt;
PHP 8.3.30&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mise à jour proposée par le dépôt OPNsense :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
OPNsense 26.1.11_10&lt;br /&gt;
79 paquets&lt;br /&gt;
307,5 Mio à télécharger&lt;br /&gt;
Redémarrage requis&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette mise à jour reste dans la branche 26.1.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Décision :&#039;&#039;&#039; reporter la mise à jour complète pour disposer d&#039;une fenêtre de maintenance suffisante.&lt;br /&gt;
&lt;br /&gt;
=== 7.3. Accès d&#039;administration à FW2 ===&lt;br /&gt;
&lt;br /&gt;
Tunnel fonctionnel depuis le Mac via HAProxy-02 :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh -N -o ExitOnForwardFailure=yes \&lt;br /&gt;
  -L 8453:10.0.0.3:453 \&lt;br /&gt;
  hpr@10.0.0.31&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Accès navigateur :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
https://127.0.0.1:8453/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Un problème a été constaté avec le même tunnel via HAProxy-01 :&lt;br /&gt;
&lt;br /&gt;
* FW2 répond au ping depuis HAProxy-01.&lt;br /&gt;
* Le port TCP 453 de FW2 ne répond pas depuis HAProxy-01.&lt;br /&gt;
* Le même port est accessible depuis HAProxy-02.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;À diagnostiquer :&#039;&#039;&#039; éventuelle règle de filtrage ou blocage dynamique de la source &amp;lt;code&amp;gt;10.0.0.30&amp;lt;/code&amp;gt; sur FW2.&lt;br /&gt;
&lt;br /&gt;
=== 7.4. Audit PHP sur FW2 ===&lt;br /&gt;
&lt;br /&gt;
Inventaire :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
pkg info -x &#039;^php83&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Version principale :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
php83-8.3.30&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Simulation de mise à jour :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
pkg upgrade -n -g &#039;php83*&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
23 paquets concernés&lt;br /&gt;
19 Mio à télécharger&lt;br /&gt;
4 Mio supplémentaires sur disque&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Principaux paquets :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Paquet&lt;br /&gt;
! Installé&lt;br /&gt;
! Proposé&lt;br /&gt;
|-&lt;br /&gt;
| php83&lt;br /&gt;
| 8.3.30&lt;br /&gt;
| 8.3.31&lt;br /&gt;
|-&lt;br /&gt;
| php83-phalcon&lt;br /&gt;
| 5.10.0&lt;br /&gt;
| 5.16.0&lt;br /&gt;
|-&lt;br /&gt;
| php83-phpseclib&lt;br /&gt;
| 3.0.50&lt;br /&gt;
| 3.0.55&lt;br /&gt;
|-&lt;br /&gt;
| openssl&lt;br /&gt;
| 3.0.20&lt;br /&gt;
| 3.0.21&lt;br /&gt;
|-&lt;br /&gt;
| curl&lt;br /&gt;
| 8.19.0_2&lt;br /&gt;
| 8.21.0&lt;br /&gt;
|-&lt;br /&gt;
| sqlite3&lt;br /&gt;
| 3.50.4_2&lt;br /&gt;
| 3.53.1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Une mise à jour PHP isolée aurait donc également modifié plusieurs bibliothèques système.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Décision :&#039;&#039;&#039; ne pas effectuer cette mise à jour partielle.&lt;br /&gt;
&lt;br /&gt;
=== 7.5. Audit des vulnérabilités ===&lt;br /&gt;
&lt;br /&gt;
Commande :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
pkg audit -F&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
28 problem(s) in 11 package(s) found.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Paquets concernés :&lt;br /&gt;
&lt;br /&gt;
* unbound&lt;br /&gt;
* openssl&lt;br /&gt;
* ldns&lt;br /&gt;
* python313&lt;br /&gt;
* openvpn&lt;br /&gt;
* dnsmasq&lt;br /&gt;
* curl&lt;br /&gt;
* php83&lt;br /&gt;
* openssh-portable&lt;br /&gt;
* strongswan&lt;br /&gt;
* expat&lt;br /&gt;
&lt;br /&gt;
Ces résultats justifient de ne pas différer indéfiniment la maintenance OPNsense.&lt;br /&gt;
&lt;br /&gt;
=== 7.6. Vérification du correctif PHP proposé ===&lt;br /&gt;
&lt;br /&gt;
Test de la version 8.3.31 :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
pkg audit -f /var/db/pkg/vuln.xml php83-8.3.31&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
php83-8.3.31 is vulnerable:&lt;br /&gt;
  CVE-2026-109619&lt;br /&gt;
  CVE-2026-109618&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;avis FreeBSD VuXML indique que la première version corrigée de PHP 8.3 est &#039;&#039;&#039;8.3.36&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Conclusion :&#039;&#039;&#039; le dépôt OPNsense examiné ne proposait pas encore une version PHP reconnue comme corrigée pour ces deux CVE.&lt;br /&gt;
&lt;br /&gt;
Une mise à jour complète d&#039;OPNsense reste nécessaire pour les autres vulnérabilités, mais ne doit pas être considérée comme suffisante pour PHP tant que ce point n&#039;est pas vérifié.&lt;br /&gt;
&lt;br /&gt;
=== 7.7. Identification du serveur Web OPNsense ===&lt;br /&gt;
&lt;br /&gt;
Sur FW2 :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
service php_fpm status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
php_fpm is not running.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Recherche des processus :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
ps auxww | grep -E &#039;[l]ighttpd|[p]hp-cgi|[p]hp-fpm&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Processus identifiés :&lt;br /&gt;
&lt;br /&gt;
* lighttpd&lt;br /&gt;
* php-cgi&lt;br /&gt;
&lt;br /&gt;
Fichier de configuration :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/usr/local/etc/lighttpd_webgui/lighttpd.conf&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Configuration FastCGI observée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;max-procs&amp;quot; =&amp;gt; 8,&lt;br /&gt;
&amp;quot;bin-environment&amp;quot; =&amp;gt; (&lt;br /&gt;
    &amp;quot;PHP_FCGI_CHILDREN&amp;quot; =&amp;gt; &amp;quot;5&amp;quot;,&lt;br /&gt;
    &amp;quot;PHP_FCGI_MAX_REQUESTS&amp;quot; =&amp;gt; &amp;quot;100&amp;quot;&lt;br /&gt;
),&lt;br /&gt;
&amp;quot;bin-path&amp;quot; =&amp;gt; &amp;quot;/usr/local/bin/php-cgi&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Conclusion :&#039;&#039;&#039; l&#039;interface d&#039;administration OPNsense utilise lighttpd avec PHP-CGI, et non PHP-FPM.&lt;br /&gt;
&lt;br /&gt;
=== 7.8. Atténuation appliquée sur FW2 ===&lt;br /&gt;
&lt;br /&gt;
État initial :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Loaded Configuration File =&amp;gt; /usr/local/etc/php.ini&lt;br /&gt;
session.upload_progress.enabled =&amp;gt; On =&amp;gt; On&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le paramètre n&#039;était défini explicitement ni dans &amp;lt;code&amp;gt;php.ini&amp;lt;/code&amp;gt; ni dans les fichiers complémentaires examinés.&lt;br /&gt;
&lt;br /&gt;
Sauvegarde :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
cp -p /usr/local/etc/php.ini \&lt;br /&gt;
  /usr/local/etc/php.ini.bak-20261022&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Modification :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
printf &#039;\n; Mitigation provisoire PHP2Shell\nsession.upload_progress.enabled = Off\n&#039; &amp;gt;&amp;gt; /usr/local/etc/php.ini&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Contrôle :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
php -i | grep session.upload_progress.enabled&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
session.upload_progress.enabled =&amp;gt; Off =&amp;gt; Off&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le redémarrage classique de lighttpd a été refusé :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Cannot &#039;restart&#039; lighttpd.&lt;br /&gt;
Set lighttpd_enable to YES in /etc/rc.conf&lt;br /&gt;
or use &#039;onerestart&#039; instead of &#039;restart&#039;.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Commande de redémarrage retenue :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
service lighttpd onerestart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;intervention a été signalée comme terminée.&lt;br /&gt;
&lt;br /&gt;
=== 7.9. Atténuation appliquée sur FW1 ===&lt;br /&gt;
&lt;br /&gt;
La console OPNsense utilise &amp;lt;code&amp;gt;csh&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Les commandes saisies avec &amp;lt;code&amp;gt;&amp;amp;amp;&amp;amp;amp;&amp;lt;/code&amp;gt; en fin de ligne ont provoqué :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Invalid null command.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les commandes ont donc été exécutées séparément.&lt;br /&gt;
&lt;br /&gt;
Sauvegarde :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
cp -p /usr/local/etc/php.ini \&lt;br /&gt;
  /usr/local/etc/php.ini.bak-20261022&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Modification :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
printf &#039;\n; Mitigation provisoire PHP2Shell\nsession.upload_progress.enabled = Off\n&#039; &amp;gt;&amp;gt; /usr/local/etc/php.ini&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Contrôle :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
php -i | grep session.upload_progress.enabled&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
session.upload_progress.enabled =&amp;gt; Off =&amp;gt; Off&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Redémarrage demandé :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
service lighttpd onerestart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;intervention a été confirmée comme terminée.&lt;br /&gt;
&lt;br /&gt;
=== 7.10. État des deux pare-feu ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Contrôle&lt;br /&gt;
! FW1&lt;br /&gt;
! FW2&lt;br /&gt;
|-&lt;br /&gt;
| Sauvegarde php.ini&lt;br /&gt;
| Effectuée&lt;br /&gt;
| Effectuée&lt;br /&gt;
|-&lt;br /&gt;
| upload_progress désactivé&lt;br /&gt;
| Oui&lt;br /&gt;
| Oui&lt;br /&gt;
|-&lt;br /&gt;
| Vérification PHP CLI&lt;br /&gt;
| Off&lt;br /&gt;
| Off&lt;br /&gt;
|-&lt;br /&gt;
| Redémarrage lighttpd&lt;br /&gt;
| Signalé terminé&lt;br /&gt;
| Signalé terminé&lt;br /&gt;
|-&lt;br /&gt;
| Vérification indépendante PHP-CGI&lt;br /&gt;
| À compléter&lt;br /&gt;
| À compléter&lt;br /&gt;
|-&lt;br /&gt;
| Mise à jour complète OPNsense&lt;br /&gt;
| Restante&lt;br /&gt;
| Restante&lt;br /&gt;
|-&lt;br /&gt;
| Correctif PHP définitif&lt;br /&gt;
| À vérifier&lt;br /&gt;
| Non disponible dans le dépôt examiné&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 8. Proposition de protection Coraza ==&lt;br /&gt;
&lt;br /&gt;
Des règles de filtrage supplémentaires ont été envisagées sur les deux HAProxy, notamment :&lt;br /&gt;
&lt;br /&gt;
* Blocage des cookies contenant &amp;lt;code&amp;gt;PHPSESSID&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Blocage de &amp;lt;code&amp;gt;PHPSESSID&amp;lt;/code&amp;gt; dans la chaîne de requête.&lt;br /&gt;
* Blocage des requêtes &amp;lt;code&amp;gt;multipart/form-data&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Décision : ne pas déployer globalement ces règles.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Motifs :&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;PHPSESSID&amp;lt;/code&amp;gt; est un identifiant de session PHP légitime.&lt;br /&gt;
* Le blocage de &amp;lt;code&amp;gt;multipart/form-data&amp;lt;/code&amp;gt; empêcherait des téléversements et formulaires légitimes.&lt;br /&gt;
* Les règles globales pourraient perturber Drupal, Pleade et d&#039;autres applications.&lt;br /&gt;
* Les interfaces OPNsense accessibles directement ne traversent pas nécessairement Coraza.&lt;br /&gt;
* Ces règles ne constituent pas une garantie de protection contre les deux CVE.&lt;br /&gt;
&lt;br /&gt;
Une protection WAF ciblée pourra être réétudiée après analyse des chemins d&#039;exploitation concernés.&lt;br /&gt;
&lt;br /&gt;
== 9. Travaux restant à effectuer ==&lt;br /&gt;
&lt;br /&gt;
=== 9.1. Priorité haute – OPNsense ===&lt;br /&gt;
&lt;br /&gt;
# Préparer une fenêtre de maintenance.&lt;br /&gt;
# Sauvegarder les configurations FW1 et FW2.&lt;br /&gt;
# Vérifier l&#039;accès console ou un accès indépendant du VPN hébergé sur FW1.&lt;br /&gt;
# Mettre à jour FW2 vers une version OPNsense officiellement prise en charge.&lt;br /&gt;
# Contrôler les services, l&#039;administration Web, les VPN et la haute disponibilité.&lt;br /&gt;
# Mettre à jour FW1 après validation de FW2.&lt;br /&gt;
# Vérifier les versions PHP réellement installées.&lt;br /&gt;
# Vérifier la disponibilité de PHP 8.3.36 ou d&#039;un correctif rétroporté équivalent.&lt;br /&gt;
# Relancer &amp;lt;code&amp;gt;pkg audit -F&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Vérifier la persistance de l&#039;atténuation &amp;lt;code&amp;gt;session.upload_progress.enabled = Off&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Ne supprimer l&#039;atténuation qu&#039;après validation d&#039;une correction définitive.&lt;br /&gt;
&lt;br /&gt;
=== 9.2. Priorité haute – Anciennes versions PHP ===&lt;br /&gt;
&lt;br /&gt;
Machines concernées notamment :&lt;br /&gt;
&lt;br /&gt;
* AD53 : PHP 7.2 / 7.3 / 8.0.&lt;br /&gt;
* DEVTOOLS2 : PHP 7.2.&lt;br /&gt;
* DEVTOOLS : PHP 5.6.&lt;br /&gt;
* ENCELADE : PHP 7.4.&lt;br /&gt;
* MERCURE : PHP 7.2 / 7.4 / 8.0 / 8.1.&lt;br /&gt;
&lt;br /&gt;
Actions :&lt;br /&gt;
&lt;br /&gt;
# Conserver les atténuations provisoires.&lt;br /&gt;
# Vérifier leur application effective dans les processus Web.&lt;br /&gt;
# Identifier les contraintes applicatives empêchant la montée de version.&lt;br /&gt;
# Préparer les migrations vers des versions PHP maintenues.&lt;br /&gt;
# Suivre les éventuels correctifs de sécurité fournis par les distributions ou mainteneurs concernés.&lt;br /&gt;
# Réaliser des tests applicatifs avant toute migration majeure.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; les versions PHP anciennes peuvent présenter d&#039;autres vulnérabilités indépendantes des deux CVE traitées ici.&lt;br /&gt;
&lt;br /&gt;
=== 9.3. Priorité moyenne – CENTREON-R8 ===&lt;br /&gt;
&lt;br /&gt;
* Effectuer le redémarrage nécessaire pour activer le nouveau noyau.&lt;br /&gt;
* Vérifier Centreon après redémarrage.&lt;br /&gt;
* Contrôler la collecte des métriques et les services associés.&lt;br /&gt;
&lt;br /&gt;
=== 9.4. Priorité moyenne – HAProxy ===&lt;br /&gt;
&lt;br /&gt;
* Examiner les paquets APT retenus.&lt;br /&gt;
* Contrôler la stabilité de Keepalived.&lt;br /&gt;
* Refaire un test de bascule VRRP.&lt;br /&gt;
* Vérifier la cohérence des configurations sur HAProxy-01 et HAProxy-02.&lt;br /&gt;
* Diagnostiquer le blocage d&#039;accès au port 453 de FW2 depuis HAProxy-01.&lt;br /&gt;
&lt;br /&gt;
=== 9.5. Vérifications transversales ===&lt;br /&gt;
&lt;br /&gt;
* Contrôler les versions PHP réellement utilisées par Apache, PHP-FPM et PHP-CGI.&lt;br /&gt;
* Vérifier les applications après les prochaines mises à jour.&lt;br /&gt;
* Vérifier la persistance des modifications manuelles après régénération de configuration.&lt;br /&gt;
* Conserver les sauvegardes de configuration jusqu&#039;à validation complète.&lt;br /&gt;
* Actualiser l&#039;inventaire des VM et leur état de sécurité.&lt;br /&gt;
&lt;br /&gt;
== 10. Commandes de contrôle ==&lt;br /&gt;
&lt;br /&gt;
=== 10.1. Ubuntu – Versions et mises à jour ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat /etc/os-release&lt;br /&gt;
&lt;br /&gt;
apt list --upgradable&lt;br /&gt;
&lt;br /&gt;
php -v&lt;br /&gt;
&lt;br /&gt;
php -i | grep session.upload_progress.enabled&lt;br /&gt;
&lt;br /&gt;
systemctl --failed&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 10.2. OPNsense – Versions et vulnérabilités ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
pkg info -x &#039;^php83&#039;&lt;br /&gt;
&lt;br /&gt;
pkg audit -F&lt;br /&gt;
&lt;br /&gt;
php -v&lt;br /&gt;
&lt;br /&gt;
php -i | grep session.upload_progress.enabled&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Simulation de mise à jour PHP, sans installation :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
pkg upgrade -n -g &#039;php83*&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 10.3. OPNsense – Processus Web ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
ps auxww | grep -E &#039;[l]ighttpd|[p]hp-cgi|[p]hp-fpm&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Redémarrage de lighttpd lorsque nécessaire :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
service lighttpd onerestart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 10.4. OPNsense – Retour arrière de la mitigation ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;À utiliser uniquement si la modification doit être annulée.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
cp -p /usr/local/etc/php.ini.bak-20261022 \&lt;br /&gt;
  /usr/local/etc/php.ini&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puis :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
service lighttpd onerestart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; ce retour arrière réactive potentiellement le mécanisme PHP ayant motivé l&#039;atténuation.&lt;br /&gt;
&lt;br /&gt;
== 11. Plan de reprise des interventions ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Ordre&lt;br /&gt;
! Machine(s)&lt;br /&gt;
! Action&lt;br /&gt;
! Validation attendue&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| FW2&lt;br /&gt;
| Sauvegarde et mise à jour OPNsense&lt;br /&gt;
| Services et administration fonctionnels&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| FW2&lt;br /&gt;
| Contrôle PHP et audit de sécurité&lt;br /&gt;
| Vulnérabilités restantes identifiées&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| FW1&lt;br /&gt;
| Sauvegarde et mise à jour OPNsense&lt;br /&gt;
| VPN, routage et administration fonctionnels&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| FW1 / FW2&lt;br /&gt;
| Vérification HA et configurations PHP&lt;br /&gt;
| Bascule et mitigation contrôlées&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| CENTREON-R8&lt;br /&gt;
| Redémarrage noyau&lt;br /&gt;
| Centreon et métriques fonctionnels&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| MERCURE&lt;br /&gt;
| Poursuite migration MERCURE3&lt;br /&gt;
| Réduction des dépendances PHP anciennes&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| AD53 / DEVTOOLS / ENCELADE&lt;br /&gt;
| Planification migration PHP&lt;br /&gt;
| Applications compatibles avec une branche maintenue&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| HAProxy-01 / HAProxy-02&lt;br /&gt;
| Contrôles VRRP et paquets retenus&lt;br /&gt;
| Haute disponibilité stable&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 12. Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Les interventions des 21 et 22 octobre 2026 ont permis :&lt;br /&gt;
&lt;br /&gt;
* De corriger les versions PHP sur plusieurs VM récentes.&lt;br /&gt;
* De mettre en place une atténuation provisoire sur les environnements PHP anciens.&lt;br /&gt;
* De sécuriser provisoirement les interfaces PHP des deux OPNsense.&lt;br /&gt;
* De mettre à jour les deux HAProxy et de corriger leur surveillance Keepalived.&lt;br /&gt;
* D&#039;identifier les vulnérabilités restant présentes sur OPNsense.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Les travaux ne sont pas terminés.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Les deux priorités restantes sont :&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Effectuer les mises à jour complètes des deux OPNsense dans une fenêtre de maintenance sécurisée.&#039;&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;Remplacer progressivement les anciennes versions PHP, dont la mitigation actuelle ne constitue pas un correctif définitif.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
La correction des CVE PHP devra être vérifiée à partir des versions réellement installées, des éventuels correctifs rétroportés et des avis de sécurité officiels.&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=S%C3%A9curit%C3%A9_PHP_%E2%80%93_CVE-2026-109618_/_CVE-2026-109619_%E2%80%93_Interventions_des_21_et_22_octobre_2026&amp;diff=6522</id>
		<title>Sécurité PHP – CVE-2026-109618 / CVE-2026-109619 – Interventions des 21 et 22 octobre 2026</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=S%C3%A9curit%C3%A9_PHP_%E2%80%93_CVE-2026-109618_/_CVE-2026-109619_%E2%80%93_Interventions_des_21_et_22_octobre_2026&amp;diff=6522"/>
		<updated>2026-10-22T15:09:59Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : Page créée avec «  = Sécurité PHP – CVE-2026-109618 / CVE-2026-109619 – Interventions des 21 et 22 octobre 2026 =  {| class=&amp;quot;wikitable&amp;quot; ! Élément ! Information |- | Période | 21 et... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Sécurité PHP – CVE-2026-109618 / CVE-2026-109619 – Interventions des 21 et 22 octobre 2026 =&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Élément&lt;br /&gt;
! Information&lt;br /&gt;
|-&lt;br /&gt;
| Période&lt;br /&gt;
| 21 et 22 octobre 2026&lt;br /&gt;
|-&lt;br /&gt;
| Infrastructure&lt;br /&gt;
| AJLSM – Machines virtuelles, HAProxy et OPNsense&lt;br /&gt;
|-&lt;br /&gt;
| Objet&lt;br /&gt;
| Correction ou atténuation des vulnérabilités PHP et mises à jour des systèmes&lt;br /&gt;
|-&lt;br /&gt;
| Nature des travaux&lt;br /&gt;
| Maintenance de sécurité, contrôles applicatifs, haute disponibilité&lt;br /&gt;
|-&lt;br /&gt;
| État&lt;br /&gt;
| Partiellement terminé – maintenance OPNsense et systèmes anciens à poursuivre&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 1. Synthèse ultra-courte ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Bilan :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Les vulnérabilités PHP &#039;&#039;&#039;CVE-2026-109618&#039;&#039;&#039; et &#039;&#039;&#039;CVE-2026-109619&#039;&#039;&#039; ont été identifiées.&lt;br /&gt;
* Les VM utilisant des versions PHP corrigées ont été mises à jour lorsque les paquets étaient disponibles.&lt;br /&gt;
* Les VM utilisant d&#039;anciennes versions de PHP ont reçu une &#039;&#039;&#039;atténuation provisoire&#039;&#039;&#039; par désactivation de &amp;lt;code&amp;gt;session.upload_progress.enabled&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Les deux HAProxy ont été mis à jour ; leur fonctionnement Keepalived/VRRP a été corrigé et contrôlé.&lt;br /&gt;
* Les deux OPNsense ont reçu la même atténuation PHP provisoire.&lt;br /&gt;
* &#039;&#039;&#039;Les mises à jour complètes des deux OPNsense restent à effectuer.&#039;&#039;&#039;&lt;br /&gt;
* La version PHP 8.3.31 proposée par le dépôt OPNsense ne corrige pas les deux CVE selon FreeBSD VuXML.&lt;br /&gt;
* Les anciennes branches PHP devront faire l&#039;objet d&#039;un suivi particulier : l&#039;atténuation ne constitue pas un correctif définitif.&lt;br /&gt;
&lt;br /&gt;
=== 1.1. Tableau de suivi ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Machine&lt;br /&gt;
! VMID&lt;br /&gt;
! PHP / système&lt;br /&gt;
! Intervention&lt;br /&gt;
! État&lt;br /&gt;
|-&lt;br /&gt;
| TEMPLATE3&lt;br /&gt;
| 506&lt;br /&gt;
| Ubuntu 26.04.1 ; PHP 8.4.27 / 8.5.12&lt;br /&gt;
| Versions PHP corrigées ; contrôles et redémarrage&lt;br /&gt;
| Terminé&lt;br /&gt;
|-&lt;br /&gt;
| AD64&lt;br /&gt;
| 507&lt;br /&gt;
| Ubuntu 26.04.1 ; PHP 8.4.27 / 8.5.12&lt;br /&gt;
| Versions PHP corrigées ; contrôles et redémarrage&lt;br /&gt;
| Terminé&lt;br /&gt;
|-&lt;br /&gt;
| DEVTOOLS2 / pleade.com&lt;br /&gt;
| 508&lt;br /&gt;
| PHP 7.2&lt;br /&gt;
| Mise à jour disponible + atténuation provisoire&lt;br /&gt;
| Atténué ; PHP ancien&lt;br /&gt;
|-&lt;br /&gt;
| APBP2&lt;br /&gt;
| 510&lt;br /&gt;
| Ubuntu 26.04.1 ; PHP 8.4.27 / 8.5.12&lt;br /&gt;
| Versions PHP corrigées ; contrôles et redémarrage&lt;br /&gt;
| Terminé&lt;br /&gt;
|-&lt;br /&gt;
| DEVTOOLS&lt;br /&gt;
| 513&lt;br /&gt;
| PHP 5.6&lt;br /&gt;
| Atténuation provisoire&lt;br /&gt;
| PHP ancien – suivi nécessaire&lt;br /&gt;
|-&lt;br /&gt;
| ENCELADE&lt;br /&gt;
| 514&lt;br /&gt;
| PHP 7.4&lt;br /&gt;
| Atténuation provisoire&lt;br /&gt;
| PHP ancien – suivi nécessaire&lt;br /&gt;
|-&lt;br /&gt;
| MERCURE&lt;br /&gt;
| 515&lt;br /&gt;
| Ubuntu 20.04.6 ; PHP 7.2 / 7.4 / 8.0 / 8.1&lt;br /&gt;
| Atténuation provisoire sur les quatre branches&lt;br /&gt;
| Migration vers MERCURE3 à poursuivre&lt;br /&gt;
|-&lt;br /&gt;
| CENTREON-R8&lt;br /&gt;
| 520&lt;br /&gt;
| PHP 8.2.35&lt;br /&gt;
| Mise à jour PHP et contrôles Centreon&lt;br /&gt;
| PHP corrigé ; reboot noyau restant&lt;br /&gt;
|-&lt;br /&gt;
| AD53&lt;br /&gt;
| —&lt;br /&gt;
| PHP 7.2 / 7.3 / 8.0&lt;br /&gt;
| Atténuation provisoire dans les configurations PHP&lt;br /&gt;
| Atténué ; PHP ancien&lt;br /&gt;
|-&lt;br /&gt;
| HAProxy-01&lt;br /&gt;
| —&lt;br /&gt;
| Ubuntu 24.04 LTS&lt;br /&gt;
| Mise à jour OS, HAProxy et Keepalived&lt;br /&gt;
| Opérationnel&lt;br /&gt;
|-&lt;br /&gt;
| HAProxy-02&lt;br /&gt;
| —&lt;br /&gt;
| Ubuntu 24.04 LTS&lt;br /&gt;
| Mise à jour OS, HAProxy et Keepalived&lt;br /&gt;
| Opérationnel&lt;br /&gt;
|-&lt;br /&gt;
| SaturneFW1&lt;br /&gt;
| —&lt;br /&gt;
| OPNsense 26.1 ; PHP 8.3&lt;br /&gt;
| Atténuation PHP provisoire&lt;br /&gt;
| Mise à jour OPNsense restante&lt;br /&gt;
|-&lt;br /&gt;
| SaturneFW2&lt;br /&gt;
| —&lt;br /&gt;
| OPNsense 26.1.6 ; PHP 8.3.30&lt;br /&gt;
| Audit et atténuation PHP provisoire&lt;br /&gt;
| Mise à jour OPNsense restante&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; ce tableau reprend les machines dont les interventions ont été identifiées dans le suivi. Il ne constitue pas, à lui seul, un inventaire exhaustif de toutes les VM Proxmox.&lt;br /&gt;
&lt;br /&gt;
== 2. Origine de l&#039;intervention ==&lt;br /&gt;
&lt;br /&gt;
=== 2.1. Vulnérabilités PHP ===&lt;br /&gt;
&lt;br /&gt;
Deux vulnérabilités critiques ont motivé l&#039;intervention :&lt;br /&gt;
&lt;br /&gt;
* CVE-2026-109618&lt;br /&gt;
* CVE-2026-109619&lt;br /&gt;
&lt;br /&gt;
L&#039;avis FreeBSD VuXML publié le 21 octobre 2026 indique que ces vulnérabilités peuvent permettre une exécution de code à distance sans authentification, selon les conditions d&#039;exploitation.&lt;br /&gt;
&lt;br /&gt;
Référence :&lt;br /&gt;
&lt;br /&gt;
https://vuxml.FreeBSD.org/freebsd/d8e16d08-cd2f-11f1-8135-8447094a420f.html&lt;br /&gt;
&lt;br /&gt;
=== 2.2. Versions corrigées ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Branche PHP&lt;br /&gt;
! Première version corrigée&lt;br /&gt;
|-&lt;br /&gt;
| PHP 8.2&lt;br /&gt;
| 8.2.35&lt;br /&gt;
|-&lt;br /&gt;
| PHP 8.3&lt;br /&gt;
| 8.3.36&lt;br /&gt;
|-&lt;br /&gt;
| PHP 8.4&lt;br /&gt;
| 8.4.27&lt;br /&gt;
|-&lt;br /&gt;
| PHP 8.5&lt;br /&gt;
| 8.5.12&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les versions plus anciennes, notamment PHP 5.6, 7.2, 7.3, 7.4, 8.0 et 8.1, ne disposent pas d&#039;une version corrigée dans les branches officielles encore maintenues.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Conséquence :&#039;&#039;&#039; sur les serveurs anciens, la désactivation de la progression des téléversements PHP est une atténuation provisoire, et non une correction complète.&lt;br /&gt;
&lt;br /&gt;
== 3. Méthode de traitement ==&lt;br /&gt;
&lt;br /&gt;
Les interventions ont été organisées machine par machine :&lt;br /&gt;
&lt;br /&gt;
# Identifier la version de l&#039;OS.&lt;br /&gt;
# Identifier toutes les versions PHP installées.&lt;br /&gt;
# Déterminer les versions réellement utilisées par Apache ou PHP-FPM.&lt;br /&gt;
# Vérifier la disponibilité des mises à jour.&lt;br /&gt;
# Appliquer les correctifs PHP disponibles.&lt;br /&gt;
# Lorsque les correctifs ne sont pas disponibles, désactiver la progression des téléversements PHP.&lt;br /&gt;
# Redémarrer ou recharger les services concernés.&lt;br /&gt;
# Vérifier les versions PHP effectives.&lt;br /&gt;
# Contrôler le fonctionnement des applications.&lt;br /&gt;
# Identifier les redémarrages système encore nécessaires.&lt;br /&gt;
&lt;br /&gt;
=== 3.1. Commandes générales de diagnostic ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat /etc/os-release&lt;br /&gt;
&lt;br /&gt;
php -v&lt;br /&gt;
&lt;br /&gt;
php -i | grep -E \&lt;br /&gt;
  &#039;Loaded Configuration File|Scan this dir|session.upload_progress.enabled&#039;&lt;br /&gt;
&lt;br /&gt;
systemctl --type=service --state=running \&lt;br /&gt;
  | grep -Ei &#039;apache|php.*fpm&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sur Ubuntu :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt list --upgradable&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La disponibilité d&#039;un correctif ne doit pas être déduite uniquement du numéro de version PHP lorsque la distribution applique des correctifs rétroportés.&lt;br /&gt;
&lt;br /&gt;
== 4. Atténuation provisoire PHP ==&lt;br /&gt;
&lt;br /&gt;
=== 4.1. Principe ===&lt;br /&gt;
&lt;br /&gt;
La mesure retenue consiste à désactiver :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
session.upload_progress.enabled = Off&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Elle empêche PHP d&#039;utiliser le mécanisme de suivi de progression des téléversements.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Limites :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Elle réduit l&#039;exposition à certains chemins d&#039;exploitation.&lt;br /&gt;
* Elle ne corrige pas nécessairement les deux CVE.&lt;br /&gt;
* Elle ne remplace pas une mise à jour de sécurité.&lt;br /&gt;
* Elle doit être appliquée à toutes les configurations PHP réellement utilisées par le serveur Web.&lt;br /&gt;
* Une vérification en PHP CLI ne garantit pas, à elle seule, la configuration effective des processus Web.&lt;br /&gt;
&lt;br /&gt;
=== 4.2. Contrôle ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php -i | grep session.upload_progress.enabled&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat attendu :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
session.upload_progress.enabled =&amp;gt; Off =&amp;gt; Off&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sur les systèmes utilisant plusieurs versions PHP, chaque branche doit être contrôlée séparément.&lt;br /&gt;
&lt;br /&gt;
== 5. Interventions sur les machines virtuelles ==&lt;br /&gt;
&lt;br /&gt;
=== 5.1. TEMPLATE3 – VM 506 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Système :&#039;&#039;&#039; Ubuntu 26.04.1 LTS.&lt;br /&gt;
&lt;br /&gt;
Versions PHP présentes après intervention :&lt;br /&gt;
&lt;br /&gt;
* PHP 8.4.27&lt;br /&gt;
* PHP 8.5.12&lt;br /&gt;
&lt;br /&gt;
Ces versions correspondent aux premières versions corrigées identifiées dans l&#039;avis de sécurité.&lt;br /&gt;
&lt;br /&gt;
Contrôles effectués :&lt;br /&gt;
&lt;br /&gt;
* Versions PHP installées.&lt;br /&gt;
* Utilisation de PHP 8.4 par Apache.&lt;br /&gt;
* Vérification des configurations.&lt;br /&gt;
* Redémarrage de la VM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;État :&#039;&#039;&#039; intervention terminée pour les vulnérabilités PHP concernées.&lt;br /&gt;
&lt;br /&gt;
=== 5.2. AD64 – VM 507 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Système :&#039;&#039;&#039; Ubuntu 26.04.1 LTS.&lt;br /&gt;
&lt;br /&gt;
Versions PHP :&lt;br /&gt;
&lt;br /&gt;
* PHP 8.4.27&lt;br /&gt;
* PHP 8.5.12&lt;br /&gt;
&lt;br /&gt;
Interventions :&lt;br /&gt;
&lt;br /&gt;
* Mise à jour des versions PHP.&lt;br /&gt;
* Contrôle de la configuration Apache.&lt;br /&gt;
* Vérification de la version PHP utilisée par le serveur Web.&lt;br /&gt;
* Redémarrage de la VM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;État :&#039;&#039;&#039; versions PHP corrigées installées.&lt;br /&gt;
&lt;br /&gt;
Les contrôles fonctionnels Drupal/Pleade doivent rester intégrés à la validation des prochaines maintenances.&lt;br /&gt;
&lt;br /&gt;
=== 5.3. APBP2 – VM 510 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Système :&#039;&#039;&#039; Ubuntu 26.04.1 LTS.&lt;br /&gt;
&lt;br /&gt;
Versions PHP :&lt;br /&gt;
&lt;br /&gt;
* PHP 8.4.27&lt;br /&gt;
* PHP 8.5.12&lt;br /&gt;
&lt;br /&gt;
Interventions :&lt;br /&gt;
&lt;br /&gt;
* Mise à jour PHP.&lt;br /&gt;
* Vérification de la configuration Apache utilisant PHP 8.4.&lt;br /&gt;
* Contrôle des services.&lt;br /&gt;
* Redémarrage de la VM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;État :&#039;&#039;&#039; versions PHP corrigées installées.&lt;br /&gt;
&lt;br /&gt;
=== 5.4. DEVTOOLS2 / pleade.com – VM 508 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Version PHP :&#039;&#039;&#039; branche 7.2.&lt;br /&gt;
&lt;br /&gt;
Mise à jour constatée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
PHP 7.2 -&amp;gt; 7.2.24.17&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La branche PHP 7.2 étant ancienne, cette mise à jour ne doit pas être assimilée à une correction définitive des deux CVE.&lt;br /&gt;
&lt;br /&gt;
Atténuation appliquée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
session.upload_progress.enabled = Off&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Contrôles réalisés :&lt;br /&gt;
&lt;br /&gt;
* Configuration PHP.&lt;br /&gt;
* Fonctionnement d&#039;Apache.&lt;br /&gt;
* Fonctionnement de Mantis.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;État :&#039;&#039;&#039; service fonctionnel avec atténuation provisoire.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;À faire :&#039;&#039;&#039; planifier le remplacement de PHP 7.2 par une branche maintenue, sous réserve de compatibilité applicative.&lt;br /&gt;
&lt;br /&gt;
=== 5.5. DEVTOOLS – VM 513 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Version PHP :&#039;&#039;&#039; PHP 5.6.&lt;br /&gt;
&lt;br /&gt;
Mesure appliquée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
session.upload_progress.enabled = Off&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;État :&#039;&#039;&#039; atténuation provisoire.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;À faire :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Identifier les dépendances applicatives à PHP 5.6.&lt;br /&gt;
* Préparer une migration vers une version PHP maintenue.&lt;br /&gt;
* Vérifier les autres mécanismes de réduction d&#039;exposition disponibles.&lt;br /&gt;
&lt;br /&gt;
=== 5.6. ENCELADE – VM 514 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Version PHP :&#039;&#039;&#039; PHP 7.4.&lt;br /&gt;
&lt;br /&gt;
Atténuation appliquée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
session.upload_progress.enabled = Off&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;État :&#039;&#039;&#039; atténuation provisoire.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;À faire :&#039;&#039;&#039; migration vers une version PHP maintenue ou remplacement de l&#039;environnement ancien.&lt;br /&gt;
&lt;br /&gt;
=== 5.7. MERCURE – VM 515 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Système :&#039;&#039;&#039; Ubuntu 20.04.6 LTS.&lt;br /&gt;
&lt;br /&gt;
Versions PHP-FPM identifiées :&lt;br /&gt;
&lt;br /&gt;
* PHP 7.2&lt;br /&gt;
* PHP 7.4&lt;br /&gt;
* PHP 8.0&lt;br /&gt;
* PHP 8.1&lt;br /&gt;
&lt;br /&gt;
La mesure provisoire a été appliquée aux quatre branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
session.upload_progress.enabled = Off&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Contrôles réalisés :&lt;br /&gt;
&lt;br /&gt;
* Services PHP-FPM actifs.&lt;br /&gt;
* Vérification des configurations.&lt;br /&gt;
* Contrôle HTTP : réponse 200.&lt;br /&gt;
* Vérification de l&#039;état applicatif.&lt;br /&gt;
&lt;br /&gt;
Aucune mise à jour de paquet n&#039;a été réalisée pendant cette intervention.&lt;br /&gt;
&lt;br /&gt;
Des extensions manquantes avaient également été relevées pour PHP 7.2, notamment concernant memcache et uploadprogress.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;État :&#039;&#039;&#039; atténuation appliquée ; applications accessibles.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Suite prévue :&#039;&#039;&#039; poursuivre la migration vers MERCURE3, plutôt que maintenir durablement cet environnement PHP ancien.&lt;br /&gt;
&lt;br /&gt;
=== 5.8. CENTREON-R8 – VM 520 ===&lt;br /&gt;
&lt;br /&gt;
Mise à jour PHP effectuée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
PHP 8.2.30 -&amp;gt; PHP 8.2.35&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Contrôles réalisés :&lt;br /&gt;
&lt;br /&gt;
* PHP-FPM 8.2.35 opérationnel.&lt;br /&gt;
* Extension SourceGuardian opérationnelle.&lt;br /&gt;
* Interface Centreon fonctionnelle.&lt;br /&gt;
* Métriques Centreon disponibles.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;État :&#039;&#039;&#039; PHP corrigé.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Reste à faire :&#039;&#039;&#039; redémarrage de la VM pour activer le noyau système mis à jour.&lt;br /&gt;
&lt;br /&gt;
=== 5.9. AD53 ===&lt;br /&gt;
&lt;br /&gt;
Versions PHP concernées :&lt;br /&gt;
&lt;br /&gt;
* PHP 7.2&lt;br /&gt;
* PHP 7.3&lt;br /&gt;
* PHP 8.0&lt;br /&gt;
&lt;br /&gt;
L&#039;intervention a porté sur &#039;&#039;&#039;11 fichiers php.ini&#039;&#039;&#039; correspondant aux différentes versions et aux différents contextes d&#039;exécution.&lt;br /&gt;
&lt;br /&gt;
Mesure appliquée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
session.upload_progress.enabled = Off&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Contrôles réalisés :&lt;br /&gt;
&lt;br /&gt;
* Vérification des configurations PHP.&lt;br /&gt;
* Redémarrage ou rechargement des services PHP-FPM concernés.&lt;br /&gt;
* Contrôle d&#039;Apache.&lt;br /&gt;
* Vérification du fonctionnement applicatif.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;État :&#039;&#039;&#039; atténuation provisoire appliquée.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; ces versions PHP restent anciennes. La désactivation de la progression des téléversements ne constitue pas une correction complète des vulnérabilités.&lt;br /&gt;
&lt;br /&gt;
== 6. HAProxy-01 et HAProxy-02 ==&lt;br /&gt;
&lt;br /&gt;
=== 6.1. Architecture ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Serveur&lt;br /&gt;
! Adresse&lt;br /&gt;
! Rôle&lt;br /&gt;
|-&lt;br /&gt;
| HAProxy-01&lt;br /&gt;
| 10.0.0.30&lt;br /&gt;
| MASTER nominal&lt;br /&gt;
|-&lt;br /&gt;
| HAProxy-02&lt;br /&gt;
| 10.0.0.31&lt;br /&gt;
| BACKUP nominal&lt;br /&gt;
|-&lt;br /&gt;
| VIP&lt;br /&gt;
| 10.0.0.32&lt;br /&gt;
| Adresse virtuelle Keepalived&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 6.2. Mises à jour ===&lt;br /&gt;
&lt;br /&gt;
Les deux serveurs ont été mis à jour vers un état Ubuntu 24.04 LTS cohérent.&lt;br /&gt;
&lt;br /&gt;
Versions vérifiées :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Ubuntu 24.04 LTS&lt;br /&gt;
Linux 6.8.0-147-generic&lt;br /&gt;
HAProxy 2.8.16&lt;br /&gt;
Keepalived 2.2.8&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les mises à jour ont concerné environ 182 et 177 paquets selon les opérations examinées.&lt;br /&gt;
&lt;br /&gt;
Six paquets étaient temporairement retenus dans les résultats APT.&lt;br /&gt;
&lt;br /&gt;
Les services suivants ont été contrôlés :&lt;br /&gt;
&lt;br /&gt;
* HAProxy&lt;br /&gt;
* Keepalived&lt;br /&gt;
* systemd-networkd&lt;br /&gt;
&lt;br /&gt;
Aucun PHP installé par APT n&#039;a été identifié sur ces deux machines.&lt;br /&gt;
&lt;br /&gt;
=== 6.3. Incident Keepalived ===&lt;br /&gt;
&lt;br /&gt;
Pendant les mises à jour, des redémarrages de Keepalived ont provoqué des changements temporaires de rôle VRRP.&lt;br /&gt;
&lt;br /&gt;
Un problème de droits a également été identifié dans le script de contrôle HAProxy.&lt;br /&gt;
&lt;br /&gt;
Le script &amp;lt;code&amp;gt;chk_haproxy&amp;lt;/code&amp;gt; était exécuté sous un compte ne disposant pas des permissions nécessaires pour contrôler les processus HAProxy.&lt;br /&gt;
&lt;br /&gt;
Correction :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
user root&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette directive a été ajoutée dans le bloc &amp;lt;code&amp;gt;vrrp_script chk_haproxy&amp;lt;/code&amp;gt;, en conservant les autres paramètres existants.&lt;br /&gt;
&lt;br /&gt;
Priorités VRRP :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
HAProxy-01 : 103&lt;br /&gt;
HAProxy-02 : 102&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
État final :&lt;br /&gt;
&lt;br /&gt;
* HAProxy-01 : MASTER.&lt;br /&gt;
* HAProxy-02 : BACKUP.&lt;br /&gt;
* VIP présente sur HAProxy-01.&lt;br /&gt;
&lt;br /&gt;
=== 6.4. Test fonctionnel ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl --resolve archives.lamayenne.fr:443:10.0.0.32 \&lt;br /&gt;
  https://archives.lamayenne.fr/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
HTTP 200&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;État :&#039;&#039;&#039; fonctionnement confirmé pour le service testé.&lt;br /&gt;
&lt;br /&gt;
=== 6.5. Points restant à vérifier ===&lt;br /&gt;
&lt;br /&gt;
* Examiner les paquets APT retenus.&lt;br /&gt;
* Confirmer la stabilité de Keepalived lors des prochaines mises à jour.&lt;br /&gt;
* Refaire un test de bascule VRRP dans une fenêtre de maintenance.&lt;br /&gt;
* Vérifier la cohérence des configurations et certificats sur les deux HAProxy.&lt;br /&gt;
&lt;br /&gt;
Les certificats et certaines configurations sont déployés séparément sur HAProxy-01 et HAProxy-02 : leur synchronisation ne doit pas être présumée automatique.&lt;br /&gt;
&lt;br /&gt;
== 7. OPNsense – SaturneFW1 et SaturneFW2 ==&lt;br /&gt;
&lt;br /&gt;
=== 7.1. Architecture ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Pare-feu&lt;br /&gt;
! Adresse&lt;br /&gt;
! Fonction&lt;br /&gt;
|-&lt;br /&gt;
| SaturneFW1&lt;br /&gt;
| 10.0.0.2&lt;br /&gt;
| Principal&lt;br /&gt;
|-&lt;br /&gt;
| SaturneFW2&lt;br /&gt;
| 10.0.0.3&lt;br /&gt;
| Secondaire&lt;br /&gt;
|-&lt;br /&gt;
| Interface Web&lt;br /&gt;
| TCP 453&lt;br /&gt;
| Administration HTTPS&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
L&#039;accès distant d&#039;administration dépend notamment d&#039;un VPN OpenVPN hébergé sur FW1.&lt;br /&gt;
&lt;br /&gt;
Cette dépendance doit être prise en compte avant toute mise à jour ou redémarrage de FW1.&lt;br /&gt;
&lt;br /&gt;
=== 7.2. État des versions ===&lt;br /&gt;
&lt;br /&gt;
Sur FW2, les versions suivantes ont été constatées :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
OPNsense 26.1.6&lt;br /&gt;
FreeBSD 14 amd64&lt;br /&gt;
PHP 8.3.30&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mise à jour proposée par le dépôt OPNsense :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
OPNsense 26.1.11_10&lt;br /&gt;
79 paquets&lt;br /&gt;
307,5 Mio à télécharger&lt;br /&gt;
Redémarrage requis&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette mise à jour reste dans la branche 26.1.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Décision :&#039;&#039;&#039; reporter la mise à jour complète pour disposer d&#039;une fenêtre de maintenance suffisante.&lt;br /&gt;
&lt;br /&gt;
=== 7.3. Accès d&#039;administration à FW2 ===&lt;br /&gt;
&lt;br /&gt;
Tunnel fonctionnel depuis le Mac via HAProxy-02 :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh -N -o ExitOnForwardFailure=yes \&lt;br /&gt;
  -L 8453:10.0.0.3:453 \&lt;br /&gt;
  hpr@10.0.0.31&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Accès navigateur :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
https://127.0.0.1:8453/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Un problème a été constaté avec le même tunnel via HAProxy-01 :&lt;br /&gt;
&lt;br /&gt;
* FW2 répond au ping depuis HAProxy-01.&lt;br /&gt;
* Le port TCP 453 de FW2 ne répond pas depuis HAProxy-01.&lt;br /&gt;
* Le même port est accessible depuis HAProxy-02.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;À diagnostiquer :&#039;&#039;&#039; éventuelle règle de filtrage ou blocage dynamique de la source &amp;lt;code&amp;gt;10.0.0.30&amp;lt;/code&amp;gt; sur FW2.&lt;br /&gt;
&lt;br /&gt;
=== 7.4. Audit PHP sur FW2 ===&lt;br /&gt;
&lt;br /&gt;
Inventaire :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
pkg info -x &#039;^php83&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Version principale :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
php83-8.3.30&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Simulation de mise à jour :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
pkg upgrade -n -g &#039;php83*&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
23 paquets concernés&lt;br /&gt;
19 Mio à télécharger&lt;br /&gt;
4 Mio supplémentaires sur disque&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Principaux paquets :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Paquet&lt;br /&gt;
! Installé&lt;br /&gt;
! Proposé&lt;br /&gt;
|-&lt;br /&gt;
| php83&lt;br /&gt;
| 8.3.30&lt;br /&gt;
| 8.3.31&lt;br /&gt;
|-&lt;br /&gt;
| php83-phalcon&lt;br /&gt;
| 5.10.0&lt;br /&gt;
| 5.16.0&lt;br /&gt;
|-&lt;br /&gt;
| php83-phpseclib&lt;br /&gt;
| 3.0.50&lt;br /&gt;
| 3.0.55&lt;br /&gt;
|-&lt;br /&gt;
| openssl&lt;br /&gt;
| 3.0.20&lt;br /&gt;
| 3.0.21&lt;br /&gt;
|-&lt;br /&gt;
| curl&lt;br /&gt;
| 8.19.0_2&lt;br /&gt;
| 8.21.0&lt;br /&gt;
|-&lt;br /&gt;
| sqlite3&lt;br /&gt;
| 3.50.4_2&lt;br /&gt;
| 3.53.1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Une mise à jour PHP isolée aurait donc également modifié plusieurs bibliothèques système.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Décision :&#039;&#039;&#039; ne pas effectuer cette mise à jour partielle.&lt;br /&gt;
&lt;br /&gt;
=== 7.5. Audit des vulnérabilités ===&lt;br /&gt;
&lt;br /&gt;
Commande :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
pkg audit -F&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
28 problem(s) in 11 package(s) found.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Paquets concernés :&lt;br /&gt;
&lt;br /&gt;
* unbound&lt;br /&gt;
* openssl&lt;br /&gt;
* ldns&lt;br /&gt;
* python313&lt;br /&gt;
* openvpn&lt;br /&gt;
* dnsmasq&lt;br /&gt;
* curl&lt;br /&gt;
* php83&lt;br /&gt;
* openssh-portable&lt;br /&gt;
* strongswan&lt;br /&gt;
* expat&lt;br /&gt;
&lt;br /&gt;
Ces résultats justifient de ne pas différer indéfiniment la maintenance OPNsense.&lt;br /&gt;
&lt;br /&gt;
=== 7.6. Vérification du correctif PHP proposé ===&lt;br /&gt;
&lt;br /&gt;
Test de la version 8.3.31 :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
pkg audit -f /var/db/pkg/vuln.xml php83-8.3.31&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
php83-8.3.31 is vulnerable:&lt;br /&gt;
  CVE-2026-109619&lt;br /&gt;
  CVE-2026-109618&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;avis FreeBSD VuXML indique que la première version corrigée de PHP 8.3 est &#039;&#039;&#039;8.3.36&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Conclusion :&#039;&#039;&#039; le dépôt OPNsense examiné ne proposait pas encore une version PHP reconnue comme corrigée pour ces deux CVE.&lt;br /&gt;
&lt;br /&gt;
Une mise à jour complète d&#039;OPNsense reste nécessaire pour les autres vulnérabilités, mais ne doit pas être considérée comme suffisante pour PHP tant que ce point n&#039;est pas vérifié.&lt;br /&gt;
&lt;br /&gt;
=== 7.7. Identification du serveur Web OPNsense ===&lt;br /&gt;
&lt;br /&gt;
Sur FW2 :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
service php_fpm status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
php_fpm is not running.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Recherche des processus :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
ps auxww | grep -E &#039;[l]ighttpd|[p]hp-cgi|[p]hp-fpm&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Processus identifiés :&lt;br /&gt;
&lt;br /&gt;
* lighttpd&lt;br /&gt;
* php-cgi&lt;br /&gt;
&lt;br /&gt;
Fichier de configuration :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/usr/local/etc/lighttpd_webgui/lighttpd.conf&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Configuration FastCGI observée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;max-procs&amp;quot; =&amp;gt; 8,&lt;br /&gt;
&amp;quot;bin-environment&amp;quot; =&amp;gt; (&lt;br /&gt;
    &amp;quot;PHP_FCGI_CHILDREN&amp;quot; =&amp;gt; &amp;quot;5&amp;quot;,&lt;br /&gt;
    &amp;quot;PHP_FCGI_MAX_REQUESTS&amp;quot; =&amp;gt; &amp;quot;100&amp;quot;&lt;br /&gt;
),&lt;br /&gt;
&amp;quot;bin-path&amp;quot; =&amp;gt; &amp;quot;/usr/local/bin/php-cgi&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Conclusion :&#039;&#039;&#039; l&#039;interface d&#039;administration OPNsense utilise lighttpd avec PHP-CGI, et non PHP-FPM.&lt;br /&gt;
&lt;br /&gt;
=== 7.8. Atténuation appliquée sur FW2 ===&lt;br /&gt;
&lt;br /&gt;
État initial :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Loaded Configuration File =&amp;gt; /usr/local/etc/php.ini&lt;br /&gt;
session.upload_progress.enabled =&amp;gt; On =&amp;gt; On&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le paramètre n&#039;était défini explicitement ni dans &amp;lt;code&amp;gt;php.ini&amp;lt;/code&amp;gt; ni dans les fichiers complémentaires examinés.&lt;br /&gt;
&lt;br /&gt;
Sauvegarde :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
cp -p /usr/local/etc/php.ini \&lt;br /&gt;
  /usr/local/etc/php.ini.bak-20261022&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Modification :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
printf &#039;\n; Mitigation provisoire PHP2Shell\nsession.upload_progress.enabled = Off\n&#039; &amp;gt;&amp;gt; /usr/local/etc/php.ini&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Contrôle :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
php -i | grep session.upload_progress.enabled&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
session.upload_progress.enabled =&amp;gt; Off =&amp;gt; Off&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le redémarrage classique de lighttpd a été refusé :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Cannot &#039;restart&#039; lighttpd.&lt;br /&gt;
Set lighttpd_enable to YES in /etc/rc.conf&lt;br /&gt;
or use &#039;onerestart&#039; instead of &#039;restart&#039;.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Commande de redémarrage retenue :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
service lighttpd onerestart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;intervention a été signalée comme terminée.&lt;br /&gt;
&lt;br /&gt;
=== 7.9. Atténuation appliquée sur FW1 ===&lt;br /&gt;
&lt;br /&gt;
La console OPNsense utilise &amp;lt;code&amp;gt;csh&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Les commandes saisies avec &amp;lt;code&amp;gt;&amp;amp;amp;&amp;amp;amp;&amp;lt;/code&amp;gt; en fin de ligne ont provoqué :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Invalid null command.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les commandes ont donc été exécutées séparément.&lt;br /&gt;
&lt;br /&gt;
Sauvegarde :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
cp -p /usr/local/etc/php.ini \&lt;br /&gt;
  /usr/local/etc/php.ini.bak-20261022&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Modification :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
printf &#039;\n; Mitigation provisoire PHP2Shell\nsession.upload_progress.enabled = Off\n&#039; &amp;gt;&amp;gt; /usr/local/etc/php.ini&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Contrôle :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
php -i | grep session.upload_progress.enabled&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
session.upload_progress.enabled =&amp;gt; Off =&amp;gt; Off&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Redémarrage demandé :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
service lighttpd onerestart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;intervention a été confirmée comme terminée.&lt;br /&gt;
&lt;br /&gt;
=== 7.10. État des deux pare-feu ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Contrôle&lt;br /&gt;
! FW1&lt;br /&gt;
! FW2&lt;br /&gt;
|-&lt;br /&gt;
| Sauvegarde php.ini&lt;br /&gt;
| Effectuée&lt;br /&gt;
| Effectuée&lt;br /&gt;
|-&lt;br /&gt;
| upload_progress désactivé&lt;br /&gt;
| Oui&lt;br /&gt;
| Oui&lt;br /&gt;
|-&lt;br /&gt;
| Vérification PHP CLI&lt;br /&gt;
| Off&lt;br /&gt;
| Off&lt;br /&gt;
|-&lt;br /&gt;
| Redémarrage lighttpd&lt;br /&gt;
| Signalé terminé&lt;br /&gt;
| Signalé terminé&lt;br /&gt;
|-&lt;br /&gt;
| Vérification indépendante PHP-CGI&lt;br /&gt;
| À compléter&lt;br /&gt;
| À compléter&lt;br /&gt;
|-&lt;br /&gt;
| Mise à jour complète OPNsense&lt;br /&gt;
| Restante&lt;br /&gt;
| Restante&lt;br /&gt;
|-&lt;br /&gt;
| Correctif PHP définitif&lt;br /&gt;
| À vérifier&lt;br /&gt;
| Non disponible dans le dépôt examiné&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 8. Proposition de protection Coraza ==&lt;br /&gt;
&lt;br /&gt;
Des règles de filtrage supplémentaires ont été envisagées sur les deux HAProxy, notamment :&lt;br /&gt;
&lt;br /&gt;
* Blocage des cookies contenant &amp;lt;code&amp;gt;PHPSESSID&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Blocage de &amp;lt;code&amp;gt;PHPSESSID&amp;lt;/code&amp;gt; dans la chaîne de requête.&lt;br /&gt;
* Blocage des requêtes &amp;lt;code&amp;gt;multipart/form-data&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Décision : ne pas déployer globalement ces règles.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Motifs :&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;PHPSESSID&amp;lt;/code&amp;gt; est un identifiant de session PHP légitime.&lt;br /&gt;
* Le blocage de &amp;lt;code&amp;gt;multipart/form-data&amp;lt;/code&amp;gt; empêcherait des téléversements et formulaires légitimes.&lt;br /&gt;
* Les règles globales pourraient perturber Drupal, Pleade et d&#039;autres applications.&lt;br /&gt;
* Les interfaces OPNsense accessibles directement ne traversent pas nécessairement Coraza.&lt;br /&gt;
* Ces règles ne constituent pas une garantie de protection contre les deux CVE.&lt;br /&gt;
&lt;br /&gt;
Une protection WAF ciblée pourra être réétudiée après analyse des chemins d&#039;exploitation concernés.&lt;br /&gt;
&lt;br /&gt;
== 9. Travaux restant à effectuer ==&lt;br /&gt;
&lt;br /&gt;
=== 9.1. Priorité haute – OPNsense ===&lt;br /&gt;
&lt;br /&gt;
# Préparer une fenêtre de maintenance.&lt;br /&gt;
# Sauvegarder les configurations FW1 et FW2.&lt;br /&gt;
# Vérifier l&#039;accès console ou un accès indépendant du VPN hébergé sur FW1.&lt;br /&gt;
# Mettre à jour FW2 vers une version OPNsense officiellement prise en charge.&lt;br /&gt;
# Contrôler les services, l&#039;administration Web, les VPN et la haute disponibilité.&lt;br /&gt;
# Mettre à jour FW1 après validation de FW2.&lt;br /&gt;
# Vérifier les versions PHP réellement installées.&lt;br /&gt;
# Vérifier la disponibilité de PHP 8.3.36 ou d&#039;un correctif rétroporté équivalent.&lt;br /&gt;
# Relancer &amp;lt;code&amp;gt;pkg audit -F&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Vérifier la persistance de l&#039;atténuation &amp;lt;code&amp;gt;session.upload_progress.enabled = Off&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Ne supprimer l&#039;atténuation qu&#039;après validation d&#039;une correction définitive.&lt;br /&gt;
&lt;br /&gt;
=== 9.2. Priorité haute – Anciennes versions PHP ===&lt;br /&gt;
&lt;br /&gt;
Machines concernées notamment :&lt;br /&gt;
&lt;br /&gt;
* AD53 : PHP 7.2 / 7.3 / 8.0.&lt;br /&gt;
* DEVTOOLS2 : PHP 7.2.&lt;br /&gt;
* DEVTOOLS : PHP 5.6.&lt;br /&gt;
* ENCELADE : PHP 7.4.&lt;br /&gt;
* MERCURE : PHP 7.2 / 7.4 / 8.0 / 8.1.&lt;br /&gt;
&lt;br /&gt;
Actions :&lt;br /&gt;
&lt;br /&gt;
# Conserver les atténuations provisoires.&lt;br /&gt;
# Vérifier leur application effective dans les processus Web.&lt;br /&gt;
# Identifier les contraintes applicatives empêchant la montée de version.&lt;br /&gt;
# Préparer les migrations vers des versions PHP maintenues.&lt;br /&gt;
# Suivre les éventuels correctifs de sécurité fournis par les distributions ou mainteneurs concernés.&lt;br /&gt;
# Réaliser des tests applicatifs avant toute migration majeure.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; les versions PHP anciennes peuvent présenter d&#039;autres vulnérabilités indépendantes des deux CVE traitées ici.&lt;br /&gt;
&lt;br /&gt;
=== 9.3. Priorité moyenne – CENTREON-R8 ===&lt;br /&gt;
&lt;br /&gt;
* Effectuer le redémarrage nécessaire pour activer le nouveau noyau.&lt;br /&gt;
* Vérifier Centreon après redémarrage.&lt;br /&gt;
* Contrôler la collecte des métriques et les services associés.&lt;br /&gt;
&lt;br /&gt;
=== 9.4. Priorité moyenne – HAProxy ===&lt;br /&gt;
&lt;br /&gt;
* Examiner les paquets APT retenus.&lt;br /&gt;
* Contrôler la stabilité de Keepalived.&lt;br /&gt;
* Refaire un test de bascule VRRP.&lt;br /&gt;
* Vérifier la cohérence des configurations sur HAProxy-01 et HAProxy-02.&lt;br /&gt;
* Diagnostiquer le blocage d&#039;accès au port 453 de FW2 depuis HAProxy-01.&lt;br /&gt;
&lt;br /&gt;
=== 9.5. Vérifications transversales ===&lt;br /&gt;
&lt;br /&gt;
* Contrôler les versions PHP réellement utilisées par Apache, PHP-FPM et PHP-CGI.&lt;br /&gt;
* Vérifier les applications après les prochaines mises à jour.&lt;br /&gt;
* Vérifier la persistance des modifications manuelles après régénération de configuration.&lt;br /&gt;
* Conserver les sauvegardes de configuration jusqu&#039;à validation complète.&lt;br /&gt;
* Actualiser l&#039;inventaire des VM et leur état de sécurité.&lt;br /&gt;
&lt;br /&gt;
== 10. Commandes de contrôle ==&lt;br /&gt;
&lt;br /&gt;
=== 10.1. Ubuntu – Versions et mises à jour ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cat /etc/os-release&lt;br /&gt;
&lt;br /&gt;
apt list --upgradable&lt;br /&gt;
&lt;br /&gt;
php -v&lt;br /&gt;
&lt;br /&gt;
php -i | grep session.upload_progress.enabled&lt;br /&gt;
&lt;br /&gt;
systemctl --failed&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 10.2. OPNsense – Versions et vulnérabilités ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
pkg info -x &#039;^php83&#039;&lt;br /&gt;
&lt;br /&gt;
pkg audit -F&lt;br /&gt;
&lt;br /&gt;
php -v&lt;br /&gt;
&lt;br /&gt;
php -i | grep session.upload_progress.enabled&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Simulation de mise à jour PHP, sans installation :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
pkg upgrade -n -g &#039;php83*&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 10.3. OPNsense – Processus Web ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
ps auxww | grep -E &#039;[l]ighttpd|[p]hp-cgi|[p]hp-fpm&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Redémarrage de lighttpd lorsque nécessaire :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
service lighttpd onerestart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 10.4. OPNsense – Retour arrière de la mitigation ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;À utiliser uniquement si la modification doit être annulée.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
cp -p /usr/local/etc/php.ini.bak-20261022 \&lt;br /&gt;
  /usr/local/etc/php.ini&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puis :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
service lighttpd onerestart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; ce retour arrière réactive potentiellement le mécanisme PHP ayant motivé l&#039;atténuation.&lt;br /&gt;
&lt;br /&gt;
== 11. Plan de reprise des interventions ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Ordre&lt;br /&gt;
! Machine(s)&lt;br /&gt;
! Action&lt;br /&gt;
! Validation attendue&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| FW2&lt;br /&gt;
| Sauvegarde et mise à jour OPNsense&lt;br /&gt;
| Services et administration fonctionnels&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| FW2&lt;br /&gt;
| Contrôle PHP et audit de sécurité&lt;br /&gt;
| Vulnérabilités restantes identifiées&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| FW1&lt;br /&gt;
| Sauvegarde et mise à jour OPNsense&lt;br /&gt;
| VPN, routage et administration fonctionnels&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| FW1 / FW2&lt;br /&gt;
| Vérification HA et configurations PHP&lt;br /&gt;
| Bascule et mitigation contrôlées&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| CENTREON-R8&lt;br /&gt;
| Redémarrage noyau&lt;br /&gt;
| Centreon et métriques fonctionnels&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| MERCURE&lt;br /&gt;
| Poursuite migration MERCURE3&lt;br /&gt;
| Réduction des dépendances PHP anciennes&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| AD53 / DEVTOOLS / ENCELADE&lt;br /&gt;
| Planification migration PHP&lt;br /&gt;
| Applications compatibles avec une branche maintenue&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| HAProxy-01 / HAProxy-02&lt;br /&gt;
| Contrôles VRRP et paquets retenus&lt;br /&gt;
| Haute disponibilité stable&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 12. Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Les interventions des 21 et 22 octobre 2026 ont permis :&lt;br /&gt;
&lt;br /&gt;
* De corriger les versions PHP sur plusieurs VM récentes.&lt;br /&gt;
* De mettre en place une atténuation provisoire sur les environnements PHP anciens.&lt;br /&gt;
* De sécuriser provisoirement les interfaces PHP des deux OPNsense.&lt;br /&gt;
* De mettre à jour les deux HAProxy et de corriger leur surveillance Keepalived.&lt;br /&gt;
* D&#039;identifier les vulnérabilités restant présentes sur OPNsense.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Les travaux ne sont pas terminés.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Les deux priorités restantes sont :&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Effectuer les mises à jour complètes des deux OPNsense dans une fenêtre de maintenance sécurisée.&#039;&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;Remplacer progressivement les anciennes versions PHP, dont la mitigation actuelle ne constitue pas un correctif définitif.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
La correction des CVE PHP devra être vérifiée à partir des versions réellement installées, des éventuels correctifs rétroportés et des avis de sécurité officiels.&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=Matomo/Maintenance&amp;diff=6521</id>
		<title>Matomo/Maintenance</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=Matomo/Maintenance&amp;diff=6521"/>
		<updated>2026-10-20T11:06:50Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : /* Exemple de tâche cron */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Maintenance de Matomo =&lt;br /&gt;
&lt;br /&gt;
== Objectif ==&lt;br /&gt;
&lt;br /&gt;
Cette procédure décrit la maintenance des installations Matomo hébergées sur les VM AJLSM.&lt;br /&gt;
&lt;br /&gt;
Elle couvre :&lt;br /&gt;
&lt;br /&gt;
* La surveillance des services.&lt;br /&gt;
* Les mises à jour de Matomo.&lt;br /&gt;
* Les sauvegardes et la restauration.&lt;br /&gt;
* L&#039;archivage des statistiques.&lt;br /&gt;
* La vérification de la collecte.&lt;br /&gt;
* Les contrôles de sécurité.&lt;br /&gt;
&lt;br /&gt;
Voir également :&lt;br /&gt;
&lt;br /&gt;
* [[Matomo/Installation]]&lt;br /&gt;
* [[Matomo/Apache]]&lt;br /&gt;
* [[Matomo/Drupal]]&lt;br /&gt;
* [[Matomo/HAProxy]]&lt;br /&gt;
* [[Matomo/Debug]]&lt;br /&gt;
=== Portée de cette documentation ===&lt;br /&gt;
&lt;br /&gt;
Cette procédure est générique et s&#039;applique aux installations Matomo&lt;br /&gt;
hébergées sur les VM AJLSM.&lt;br /&gt;
&lt;br /&gt;
Les références à &#039;&#039;&#039;AD64&#039;&#039;&#039; correspondent à un exemple réel&lt;br /&gt;
d&#039;installation, vérifié en octobre 2026.&lt;br /&gt;
&lt;br /&gt;
Elles illustrent les choix techniques effectués sur ce projet,&lt;br /&gt;
mais ne constituent pas des paramètres obligatoires pour les&lt;br /&gt;
futures installations.&lt;br /&gt;
&lt;br /&gt;
Les versions logicielles, chemins, domaines, fréquences d&#039;archivage&lt;br /&gt;
et modalités de sauvegarde doivent être adaptés à chaque environnement.&lt;br /&gt;
&lt;br /&gt;
== 1. Vérifications courantes ==&lt;br /&gt;
&lt;br /&gt;
=== Version de Matomo ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /var/www/matomo&lt;br /&gt;
sudo -u www-data php console core:version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Services Apache et MariaDB ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl is-active apache2&lt;br /&gt;
systemctl is-active mariadb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Si la VM utilise PHP-FPM, vérifier également le service correspondant :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl is-active php8.4-fpm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; PHP-FPM n&#039;est pas nécessaire lorsque PHP est exécuté par Apache avec `mod_php`, comme sur AD64.&lt;br /&gt;
&lt;br /&gt;
=== Espace disque ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
df -h&lt;br /&gt;
du -sh /var/www/matomo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Taille de la base Matomo ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo mariadb -t -e &amp;quot;&lt;br /&gt;
SELECT&lt;br /&gt;
    table_schema AS base,&lt;br /&gt;
    ROUND(SUM(data_length + index_length)/1024/1024, 2) AS taille_Mo&lt;br /&gt;
FROM information_schema.tables&lt;br /&gt;
WHERE table_schema = &#039;matomo&#039;&lt;br /&gt;
GROUP BY table_schema;&lt;br /&gt;
&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La taille de la base doit être surveillée, notamment lorsque le nombre de visites et la durée de conservation des données augmentent.&lt;br /&gt;
&lt;br /&gt;
== 2. Mise à jour de Matomo ==&lt;br /&gt;
&lt;br /&gt;
=== Méthode habituelle AJLSM ===&lt;br /&gt;
&lt;br /&gt;
Les mises à jour de Matomo sont proposées directement dans son interface d&#039;administration.&lt;br /&gt;
&lt;br /&gt;
Sur AD64, les précédentes mises à jour ont été réalisées depuis cette interface, sans passer par le terminal.&lt;br /&gt;
&lt;br /&gt;
Cette méthode est retenue comme procédure habituelle.&lt;br /&gt;
&lt;br /&gt;
=== Avant la mise à jour ===&lt;br /&gt;
&lt;br /&gt;
# Vérifier la compatibilité de la nouvelle version avec PHP et MariaDB.&lt;br /&gt;
# Vérifier l&#039;espace disque disponible.&lt;br /&gt;
# Effectuer une sauvegarde de la base MariaDB.&lt;br /&gt;
# Sauvegarder les fichiers de configuration et les éventuels plugins personnalisés.&lt;br /&gt;
# Vérifier que les sauvegardes sont exploitables.&lt;br /&gt;
&lt;br /&gt;
Exemple de sauvegarde manuelle de la base :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo mariadb-dump --single-transaction \&lt;br /&gt;
  --routines --triggers --events \&lt;br /&gt;
  matomo &amp;gt; &amp;quot;$HOME/matomo-$(date +%Y%m%d-%H%M%S).sql&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; cette commande crée une sauvegarde ponctuelle dans le répertoire personnel de l&#039;utilisateur courant. Elle ne remplace pas la stratégie de sauvegarde générale de la VM.&lt;br /&gt;
&lt;br /&gt;
Vérifier également les sauvegardes existantes avant toute intervention importante.&lt;br /&gt;
&lt;br /&gt;
=== Effectuer la mise à jour ===&lt;br /&gt;
&lt;br /&gt;
# Se connecter à l&#039;administration Matomo depuis une adresse IP autorisée.&lt;br /&gt;
# Ouvrir la notification de nouvelle version.&lt;br /&gt;
# Lire les informations et les prérequis.&lt;br /&gt;
# Lancer la mise à jour depuis l&#039;interface.&lt;br /&gt;
# Effectuer, si demandé, la mise à jour de la base de données.&lt;br /&gt;
# Attendre la confirmation de fin d&#039;opération.&lt;br /&gt;
&lt;br /&gt;
Ne pas interrompre une mise à jour en cours.&lt;br /&gt;
&lt;br /&gt;
=== Après la mise à jour ===&lt;br /&gt;
&lt;br /&gt;
Vérifier :&lt;br /&gt;
&lt;br /&gt;
* La version affichée par Matomo.&lt;br /&gt;
* L&#039;accès à l&#039;interface d&#039;administration.&lt;br /&gt;
* L&#039;absence d&#039;erreurs dans les journaux.&lt;br /&gt;
* Le fonctionnement des rapports.&lt;br /&gt;
* La réception de nouvelles visites.&lt;br /&gt;
* Le fonctionnement des plugins installés.&lt;br /&gt;
&lt;br /&gt;
Commande de vérification :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /var/www/matomo&lt;br /&gt;
sudo -u www-data php console core:version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3. Sauvegardes ==&lt;br /&gt;
&lt;br /&gt;
=== Éléments à sauvegarder ===&lt;br /&gt;
&lt;br /&gt;
Une sauvegarde exploitable doit couvrir :&lt;br /&gt;
&lt;br /&gt;
* La base MariaDB `matomo`.&lt;br /&gt;
* Le fichier `/var/www/matomo/config/config.ini.php`.&lt;br /&gt;
* Les plugins ou personnalisations non fournis par l&#039;installation standard.&lt;br /&gt;
* Les autres fichiers spécifiques à l&#039;installation, s&#039;il en existe.&lt;br /&gt;
&lt;br /&gt;
Le code standard de Matomo peut être réinstallé, mais la base de données et la configuration sont indispensables à la restitution de l&#039;installation.&lt;br /&gt;
&lt;br /&gt;
=== Sauvegarde de la base ===&lt;br /&gt;
&lt;br /&gt;
Exemple de sauvegarde compressée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo mariadb-dump --single-transaction \&lt;br /&gt;
  --routines --triggers --events \&lt;br /&gt;
  matomo | gzip &amp;gt; &amp;quot;$HOME/matomo-$(date +%Y%m%d-%H%M%S).sql.gz&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Protéger les sauvegardes : elles peuvent contenir des informations sur les visiteurs et des données de configuration sensibles.&lt;br /&gt;
&lt;br /&gt;
=== Sauvegarde de la configuration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo tar -czf &amp;quot;$HOME/matomo-config-$(date +%Y%m%d-%H%M%S).tar.gz&amp;quot; \&lt;br /&gt;
  -C /var/www/matomo \&lt;br /&gt;
  config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les archives doivent être conservées dans un emplacement protégé, idéalement distinct de la VM.&lt;br /&gt;
&lt;br /&gt;
=== Sauvegardes de l&#039;infrastructure ===&lt;br /&gt;
&lt;br /&gt;
Avant d&#039;ajouter une sauvegarde spécifique, vérifier si Matomo est déjà couvert par :&lt;br /&gt;
&lt;br /&gt;
* Les sauvegardes de la VM Proxmox.&lt;br /&gt;
* Les sauvegardes applicatives existantes.&lt;br /&gt;
* Les sauvegardes MariaDB éventuellement configurées sur la VM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; la présence d&#039;une sauvegarde ne garantit pas sa restaurabilité. Un test de restauration doit être prévu.&lt;br /&gt;
&lt;br /&gt;
=== Restauration ===&lt;br /&gt;
&lt;br /&gt;
Une restauration doit être préparée en fonction de l&#039;incident.&lt;br /&gt;
&lt;br /&gt;
La procédure générale consiste à :&lt;br /&gt;
&lt;br /&gt;
# Préserver l&#039;état actuel avant toute intervention.&lt;br /&gt;
# Identifier une sauvegarde cohérente de la base et des fichiers.&lt;br /&gt;
# Restaurer dans un environnement de test lorsque cela est possible.&lt;br /&gt;
# Vérifier la compatibilité entre la version du code Matomo et le schéma de la base restaurée.&lt;br /&gt;
# Restaurer les données et la configuration.&lt;br /&gt;
# Vérifier les permissions.&lt;br /&gt;
# Tester l&#039;interface et la collecte.&lt;br /&gt;
&lt;br /&gt;
Ne pas restaurer directement une ancienne base sur une installation Matomo plus récente sans avoir vérifié la compatibilité.&lt;br /&gt;
&lt;br /&gt;
== 4. Archivage des statistiques ==&lt;br /&gt;
&lt;br /&gt;
=== Principe ===&lt;br /&gt;
&lt;br /&gt;
Matomo calcule des rapports statistiques à partir des données de visites.&lt;br /&gt;
&lt;br /&gt;
Deux méthodes principales sont possibles :&lt;br /&gt;
&lt;br /&gt;
* Archivage déclenché par la consultation des rapports dans le navigateur.&lt;br /&gt;
* Archivage automatique par une tâche planifiée exécutant `core:archive`.&lt;br /&gt;
&lt;br /&gt;
=== Méthode 1 : archivage depuis le navigateur ===&lt;br /&gt;
&lt;br /&gt;
Cette méthode est utilisée sur AD64 en octobre 2026.&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;administration Matomo :&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Administration → Système → Paramètres généraux → Paramètres d&#039;archivage&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Configuration constatée :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Paramètre&lt;br /&gt;
! Valeur AD64&lt;br /&gt;
|-&lt;br /&gt;
| Archiver les rapports lorsqu&#039;ils sont affichés depuis le navigateur&lt;br /&gt;
| Oui&lt;br /&gt;
|-&lt;br /&gt;
| Archiver les rapports au plus toutes les X secondes&lt;br /&gt;
| 900 secondes (15 minutes)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les rapports peuvent donc être calculés lors de leur consultation.&lt;br /&gt;
&lt;br /&gt;
Cette configuration convient à une installation de faible volume, notamment lors de la mise en service.&lt;br /&gt;
&lt;br /&gt;
Elle peut cependant provoquer des calculs au moment où un utilisateur consulte les statistiques.&lt;br /&gt;
&lt;br /&gt;
=== Méthode 2 : archivage automatique ===&lt;br /&gt;
&lt;br /&gt;
Pour une installation plus sollicitée, un archivage planifié est préférable.&lt;br /&gt;
&lt;br /&gt;
Matomo fournit la commande :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo -u www-data php /var/www/matomo/console core:archive&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; cette commande lance réellement l&#039;archivage. Ne pas l&#039;exécuter pour une simple vérification.&lt;br /&gt;
&lt;br /&gt;
Pour afficher les options sans lancer de traitement :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo -u www-data php /var/www/matomo/console core:archive --help&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemple de tâche cron ===&lt;br /&gt;
&lt;br /&gt;
Exemple de configuration pour un archivage toutes les heures :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
0 * * * * /usr/bin/php /var/www/matomo/console core:archive --url=https://matomo.exemple.fr/ &amp;gt;&amp;gt; /var/log/matomo-archive.log 2&amp;gt;&amp;amp;1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette ligne est un &#039;&#039;&#039;exemple de configuration&#039;&#039;&#039;, et non une tâche déjà installée sur AD64.&lt;br /&gt;
&lt;br /&gt;
Elle doit être adaptée avant utilisation :&lt;br /&gt;
&lt;br /&gt;
* À l&#039;URL réelle de Matomo.&lt;br /&gt;
* À l&#039;utilisateur d&#039;exécution PHP.&lt;br /&gt;
* Aux permissions du fichier journal.&lt;br /&gt;
* À la fréquence d&#039;archivage souhaitée.&lt;br /&gt;
* Aux restrictions réseau ou HAProxy.&lt;br /&gt;
&lt;br /&gt;
Le processus d&#039;archivage doit pouvoir joindre les ressources Matomo nécessaires. Une interface d&#039;administration protégée par HAProxy peut imposer une configuration particulière de l&#039;URL utilisée.&lt;br /&gt;
&lt;br /&gt;
=== Passage à l&#039;archivage automatique ===&lt;br /&gt;
&lt;br /&gt;
Avant de mettre en service une tâche planifiée :&lt;br /&gt;
&lt;br /&gt;
# Vérifier le bon fonctionnement de la commande `core:archive`.&lt;br /&gt;
# Vérifier que l&#039;URL utilisée est accessible depuis la VM.&lt;br /&gt;
# Configurer une tâche planifiée sous l&#039;utilisateur approprié.&lt;br /&gt;
# Vérifier les journaux d&#039;exécution.&lt;br /&gt;
# Contrôler que les rapports sont correctement actualisés.&lt;br /&gt;
# Désactiver ensuite l&#039;archivage déclenché par le navigateur dans les paramètres généraux de Matomo, conformément à la configuration retenue.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ne pas désactiver l&#039;archivage depuis le navigateur avant d&#039;avoir confirmé le fonctionnement de l&#039;archivage automatique.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== 5. Vérification de la collecte ==&lt;br /&gt;
&lt;br /&gt;
=== Tests HTTP ===&lt;br /&gt;
&lt;br /&gt;
Depuis une connexion extérieure au réseau AJLSM :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
MATOMO_URL=&amp;quot;https://matomo.exemple.fr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
for RESOURCE in matomo.js matomo.php; do&lt;br /&gt;
    echo &amp;quot;===== /$RESOURCE =====&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    curl -sS -o /dev/null -w &amp;quot;HTTP %{http_code}\n&amp;quot; \&lt;br /&gt;
      &amp;quot;$MATOMO_URL/$RESOURCE&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pour une installation utilisant les ACL HAProxy décrites dans [[Matomo/HAProxy]], les ressources de collecte doivent rester accessibles publiquement.&lt;br /&gt;
&lt;br /&gt;
=== Vérification en base ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT&lt;br /&gt;
    idsite,&lt;br /&gt;
    COUNT(*) AS visites,&lt;br /&gt;
    MAX(visit_last_action_time) AS derniere_activite&lt;br /&gt;
FROM matomo_log_visit&lt;br /&gt;
GROUP BY idsite;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La présence de visites récentes confirme que des données sont enregistrées.&lt;br /&gt;
&lt;br /&gt;
Cette requête ne permet cependant pas, à elle seule, de vérifier l&#039;exactitude de tous les rapports.&lt;br /&gt;
&lt;br /&gt;
=== Vérification depuis Drupal ===&lt;br /&gt;
&lt;br /&gt;
Consulter une page publique de l&#039;application Drupal suivie.&lt;br /&gt;
&lt;br /&gt;
Vérifier ensuite :&lt;br /&gt;
&lt;br /&gt;
* Que le script Matomo est chargé.&lt;br /&gt;
* Qu&#039;une requête de suivi est transmise.&lt;br /&gt;
* Qu&#039;aucune erreur de suivi n&#039;apparaît.&lt;br /&gt;
* Que la visite est enregistrée sur le bon identifiant de site Matomo.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Drupal]].&lt;br /&gt;
&lt;br /&gt;
== 6. Certificats et sécurité ==&lt;br /&gt;
&lt;br /&gt;
=== HTTPS ===&lt;br /&gt;
&lt;br /&gt;
Pour les installations publiées par HAProxy, le certificat public est généralement géré sur les répartiteurs.&lt;br /&gt;
&lt;br /&gt;
Vérifier la date d&#039;expiration :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
openssl s_client \&lt;br /&gt;
  -connect matomo.exemple.fr:443 \&lt;br /&gt;
  -servername matomo.exemple.fr &amp;lt;/dev/null 2&amp;gt;/dev/null \&lt;br /&gt;
  | openssl x509 -noout -subject -issuer -dates&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier également le renouvellement automatique et le déploiement effectif du certificat.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/HAProxy]].&lt;br /&gt;
&lt;br /&gt;
=== Restrictions d&#039;accès ===&lt;br /&gt;
&lt;br /&gt;
Lorsque l&#039;administration est réservée à AJLSM :&lt;br /&gt;
&lt;br /&gt;
* L&#039;interface Matomo doit être inaccessible depuis une IP extérieure non autorisée.&lt;br /&gt;
* Les points de collecte nécessaires doivent rester accessibles.&lt;br /&gt;
* L&#039;accès à l&#039;administration doit rester possible depuis le réseau autorisé.&lt;br /&gt;
&lt;br /&gt;
=== Permissions ===&lt;br /&gt;
&lt;br /&gt;
Vérifier périodiquement les permissions des fichiers sensibles :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
stat -c &#039;%A %a %U:%G %n&#039; \&lt;br /&gt;
  /var/www/matomo \&lt;br /&gt;
  /var/www/matomo/config/config.ini.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Installation]] pour les permissions recommandées.&lt;br /&gt;
&lt;br /&gt;
== 7. Journaux et diagnostic ==&lt;br /&gt;
&lt;br /&gt;
En cas de dysfonctionnement, consulter les journaux Apache :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo journalctl -u apache2 --since &amp;quot;1 hour ago&amp;quot; --no-pager&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les fichiers de logs Apache peuvent également être consultés dans `/var/log/apache2/`, selon la configuration du VirtualHost.&lt;br /&gt;
&lt;br /&gt;
Pour MariaDB :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo journalctl -u mariadb --since &amp;quot;1 hour ago&amp;quot; --no-pager&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier aussi les journaux et messages d&#039;erreur propres à Matomo.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Debug]].&lt;br /&gt;
&lt;br /&gt;
== 8. Retour d&#039;expérience AD64 — octobre 2026 ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Élément&lt;br /&gt;
! Situation constatée&lt;br /&gt;
|-&lt;br /&gt;
| Matomo&lt;br /&gt;
| Version 5.10.1&lt;br /&gt;
|-&lt;br /&gt;
| Serveur&lt;br /&gt;
| ad64&lt;br /&gt;
|-&lt;br /&gt;
| Répertoire&lt;br /&gt;
| /var/www/matomo&lt;br /&gt;
|-&lt;br /&gt;
| Serveur web&lt;br /&gt;
| Apache avec mod_php et mpm_prefork&lt;br /&gt;
|-&lt;br /&gt;
| Base de données&lt;br /&gt;
| MariaDB, base matomo&lt;br /&gt;
|-&lt;br /&gt;
| Taille de la base&lt;br /&gt;
| 5,70 Mo au 20 octobre 2026&lt;br /&gt;
|-&lt;br /&gt;
| Mise à jour Matomo&lt;br /&gt;
| Depuis l&#039;interface d&#039;administration&lt;br /&gt;
|-&lt;br /&gt;
| Archivage&lt;br /&gt;
| Déclenché depuis le navigateur&lt;br /&gt;
|-&lt;br /&gt;
| Fréquence d&#039;archivage configurée&lt;br /&gt;
| 900 secondes&lt;br /&gt;
|-&lt;br /&gt;
| Cron core:archive&lt;br /&gt;
| Aucune tâche identifiée dans les emplacements examinés&lt;br /&gt;
|-&lt;br /&gt;
| Sites suivis&lt;br /&gt;
| Drupal Internet et Salle de lecture&lt;br /&gt;
|-&lt;br /&gt;
| Administration&lt;br /&gt;
| Restreinte par HAProxy aux adresses AJLSM autorisées&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Points restant à vérifier ===&lt;br /&gt;
&lt;br /&gt;
* La couverture exacte de Matomo par les sauvegardes existantes.&lt;br /&gt;
* La présence éventuelle d&#039;une sauvegarde MariaDB indépendante.&lt;br /&gt;
* Le test de restauration.&lt;br /&gt;
* Le renouvellement effectif du certificat public lors de sa prochaine échéance.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Conclusion :&#039;&#039;&#039; AD64 fonctionne actuellement avec un archivage à la demande et des mises à jour réalisées depuis l&#039;interface Matomo. Il n&#039;est pas nécessaire de modifier immédiatement cette configuration. Pour les futures installations, les sauvegardes et l&#039;archivage automatique devront être évalués selon le volume et les exigences du projet.&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=Matomo/Maintenance&amp;diff=6520</id>
		<title>Matomo/Maintenance</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=Matomo/Maintenance&amp;diff=6520"/>
		<updated>2026-10-20T11:04:54Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : /* Objectif */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Maintenance de Matomo =&lt;br /&gt;
&lt;br /&gt;
== Objectif ==&lt;br /&gt;
&lt;br /&gt;
Cette procédure décrit la maintenance des installations Matomo hébergées sur les VM AJLSM.&lt;br /&gt;
&lt;br /&gt;
Elle couvre :&lt;br /&gt;
&lt;br /&gt;
* La surveillance des services.&lt;br /&gt;
* Les mises à jour de Matomo.&lt;br /&gt;
* Les sauvegardes et la restauration.&lt;br /&gt;
* L&#039;archivage des statistiques.&lt;br /&gt;
* La vérification de la collecte.&lt;br /&gt;
* Les contrôles de sécurité.&lt;br /&gt;
&lt;br /&gt;
Voir également :&lt;br /&gt;
&lt;br /&gt;
* [[Matomo/Installation]]&lt;br /&gt;
* [[Matomo/Apache]]&lt;br /&gt;
* [[Matomo/Drupal]]&lt;br /&gt;
* [[Matomo/HAProxy]]&lt;br /&gt;
* [[Matomo/Debug]]&lt;br /&gt;
=== Portée de cette documentation ===&lt;br /&gt;
&lt;br /&gt;
Cette procédure est générique et s&#039;applique aux installations Matomo&lt;br /&gt;
hébergées sur les VM AJLSM.&lt;br /&gt;
&lt;br /&gt;
Les références à &#039;&#039;&#039;AD64&#039;&#039;&#039; correspondent à un exemple réel&lt;br /&gt;
d&#039;installation, vérifié en octobre 2026.&lt;br /&gt;
&lt;br /&gt;
Elles illustrent les choix techniques effectués sur ce projet,&lt;br /&gt;
mais ne constituent pas des paramètres obligatoires pour les&lt;br /&gt;
futures installations.&lt;br /&gt;
&lt;br /&gt;
Les versions logicielles, chemins, domaines, fréquences d&#039;archivage&lt;br /&gt;
et modalités de sauvegarde doivent être adaptés à chaque environnement.&lt;br /&gt;
&lt;br /&gt;
== 1. Vérifications courantes ==&lt;br /&gt;
&lt;br /&gt;
=== Version de Matomo ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /var/www/matomo&lt;br /&gt;
sudo -u www-data php console core:version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Services Apache et MariaDB ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl is-active apache2&lt;br /&gt;
systemctl is-active mariadb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Si la VM utilise PHP-FPM, vérifier également le service correspondant :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl is-active php8.4-fpm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; PHP-FPM n&#039;est pas nécessaire lorsque PHP est exécuté par Apache avec `mod_php`, comme sur AD64.&lt;br /&gt;
&lt;br /&gt;
=== Espace disque ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
df -h&lt;br /&gt;
du -sh /var/www/matomo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Taille de la base Matomo ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo mariadb -t -e &amp;quot;&lt;br /&gt;
SELECT&lt;br /&gt;
    table_schema AS base,&lt;br /&gt;
    ROUND(SUM(data_length + index_length)/1024/1024, 2) AS taille_Mo&lt;br /&gt;
FROM information_schema.tables&lt;br /&gt;
WHERE table_schema = &#039;matomo&#039;&lt;br /&gt;
GROUP BY table_schema;&lt;br /&gt;
&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La taille de la base doit être surveillée, notamment lorsque le nombre de visites et la durée de conservation des données augmentent.&lt;br /&gt;
&lt;br /&gt;
== 2. Mise à jour de Matomo ==&lt;br /&gt;
&lt;br /&gt;
=== Méthode habituelle AJLSM ===&lt;br /&gt;
&lt;br /&gt;
Les mises à jour de Matomo sont proposées directement dans son interface d&#039;administration.&lt;br /&gt;
&lt;br /&gt;
Sur AD64, les précédentes mises à jour ont été réalisées depuis cette interface, sans passer par le terminal.&lt;br /&gt;
&lt;br /&gt;
Cette méthode est retenue comme procédure habituelle.&lt;br /&gt;
&lt;br /&gt;
=== Avant la mise à jour ===&lt;br /&gt;
&lt;br /&gt;
# Vérifier la compatibilité de la nouvelle version avec PHP et MariaDB.&lt;br /&gt;
# Vérifier l&#039;espace disque disponible.&lt;br /&gt;
# Effectuer une sauvegarde de la base MariaDB.&lt;br /&gt;
# Sauvegarder les fichiers de configuration et les éventuels plugins personnalisés.&lt;br /&gt;
# Vérifier que les sauvegardes sont exploitables.&lt;br /&gt;
&lt;br /&gt;
Exemple de sauvegarde manuelle de la base :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo mariadb-dump --single-transaction \&lt;br /&gt;
  --routines --triggers --events \&lt;br /&gt;
  matomo &amp;gt; &amp;quot;$HOME/matomo-$(date +%Y%m%d-%H%M%S).sql&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; cette commande crée une sauvegarde ponctuelle dans le répertoire personnel de l&#039;utilisateur courant. Elle ne remplace pas la stratégie de sauvegarde générale de la VM.&lt;br /&gt;
&lt;br /&gt;
Vérifier également les sauvegardes existantes avant toute intervention importante.&lt;br /&gt;
&lt;br /&gt;
=== Effectuer la mise à jour ===&lt;br /&gt;
&lt;br /&gt;
# Se connecter à l&#039;administration Matomo depuis une adresse IP autorisée.&lt;br /&gt;
# Ouvrir la notification de nouvelle version.&lt;br /&gt;
# Lire les informations et les prérequis.&lt;br /&gt;
# Lancer la mise à jour depuis l&#039;interface.&lt;br /&gt;
# Effectuer, si demandé, la mise à jour de la base de données.&lt;br /&gt;
# Attendre la confirmation de fin d&#039;opération.&lt;br /&gt;
&lt;br /&gt;
Ne pas interrompre une mise à jour en cours.&lt;br /&gt;
&lt;br /&gt;
=== Après la mise à jour ===&lt;br /&gt;
&lt;br /&gt;
Vérifier :&lt;br /&gt;
&lt;br /&gt;
* La version affichée par Matomo.&lt;br /&gt;
* L&#039;accès à l&#039;interface d&#039;administration.&lt;br /&gt;
* L&#039;absence d&#039;erreurs dans les journaux.&lt;br /&gt;
* Le fonctionnement des rapports.&lt;br /&gt;
* La réception de nouvelles visites.&lt;br /&gt;
* Le fonctionnement des plugins installés.&lt;br /&gt;
&lt;br /&gt;
Commande de vérification :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /var/www/matomo&lt;br /&gt;
sudo -u www-data php console core:version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3. Sauvegardes ==&lt;br /&gt;
&lt;br /&gt;
=== Éléments à sauvegarder ===&lt;br /&gt;
&lt;br /&gt;
Une sauvegarde exploitable doit couvrir :&lt;br /&gt;
&lt;br /&gt;
* La base MariaDB `matomo`.&lt;br /&gt;
* Le fichier `/var/www/matomo/config/config.ini.php`.&lt;br /&gt;
* Les plugins ou personnalisations non fournis par l&#039;installation standard.&lt;br /&gt;
* Les autres fichiers spécifiques à l&#039;installation, s&#039;il en existe.&lt;br /&gt;
&lt;br /&gt;
Le code standard de Matomo peut être réinstallé, mais la base de données et la configuration sont indispensables à la restitution de l&#039;installation.&lt;br /&gt;
&lt;br /&gt;
=== Sauvegarde de la base ===&lt;br /&gt;
&lt;br /&gt;
Exemple de sauvegarde compressée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo mariadb-dump --single-transaction \&lt;br /&gt;
  --routines --triggers --events \&lt;br /&gt;
  matomo | gzip &amp;gt; &amp;quot;$HOME/matomo-$(date +%Y%m%d-%H%M%S).sql.gz&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Protéger les sauvegardes : elles peuvent contenir des informations sur les visiteurs et des données de configuration sensibles.&lt;br /&gt;
&lt;br /&gt;
=== Sauvegarde de la configuration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo tar -czf &amp;quot;$HOME/matomo-config-$(date +%Y%m%d-%H%M%S).tar.gz&amp;quot; \&lt;br /&gt;
  -C /var/www/matomo \&lt;br /&gt;
  config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les archives doivent être conservées dans un emplacement protégé, idéalement distinct de la VM.&lt;br /&gt;
&lt;br /&gt;
=== Sauvegardes de l&#039;infrastructure ===&lt;br /&gt;
&lt;br /&gt;
Avant d&#039;ajouter une sauvegarde spécifique, vérifier si Matomo est déjà couvert par :&lt;br /&gt;
&lt;br /&gt;
* Les sauvegardes de la VM Proxmox.&lt;br /&gt;
* Les sauvegardes applicatives existantes.&lt;br /&gt;
* Les sauvegardes MariaDB éventuellement configurées sur la VM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; la présence d&#039;une sauvegarde ne garantit pas sa restaurabilité. Un test de restauration doit être prévu.&lt;br /&gt;
&lt;br /&gt;
=== Restauration ===&lt;br /&gt;
&lt;br /&gt;
Une restauration doit être préparée en fonction de l&#039;incident.&lt;br /&gt;
&lt;br /&gt;
La procédure générale consiste à :&lt;br /&gt;
&lt;br /&gt;
# Préserver l&#039;état actuel avant toute intervention.&lt;br /&gt;
# Identifier une sauvegarde cohérente de la base et des fichiers.&lt;br /&gt;
# Restaurer dans un environnement de test lorsque cela est possible.&lt;br /&gt;
# Vérifier la compatibilité entre la version du code Matomo et le schéma de la base restaurée.&lt;br /&gt;
# Restaurer les données et la configuration.&lt;br /&gt;
# Vérifier les permissions.&lt;br /&gt;
# Tester l&#039;interface et la collecte.&lt;br /&gt;
&lt;br /&gt;
Ne pas restaurer directement une ancienne base sur une installation Matomo plus récente sans avoir vérifié la compatibilité.&lt;br /&gt;
&lt;br /&gt;
== 4. Archivage des statistiques ==&lt;br /&gt;
&lt;br /&gt;
=== Principe ===&lt;br /&gt;
&lt;br /&gt;
Matomo calcule des rapports statistiques à partir des données de visites.&lt;br /&gt;
&lt;br /&gt;
Deux méthodes principales sont possibles :&lt;br /&gt;
&lt;br /&gt;
* Archivage déclenché par la consultation des rapports dans le navigateur.&lt;br /&gt;
* Archivage automatique par une tâche planifiée exécutant `core:archive`.&lt;br /&gt;
&lt;br /&gt;
=== Méthode 1 : archivage depuis le navigateur ===&lt;br /&gt;
&lt;br /&gt;
Cette méthode est utilisée sur AD64 en octobre 2026.&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;administration Matomo :&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Administration → Système → Paramètres généraux → Paramètres d&#039;archivage&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Configuration constatée :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Paramètre&lt;br /&gt;
! Valeur AD64&lt;br /&gt;
|-&lt;br /&gt;
| Archiver les rapports lorsqu&#039;ils sont affichés depuis le navigateur&lt;br /&gt;
| Oui&lt;br /&gt;
|-&lt;br /&gt;
| Archiver les rapports au plus toutes les X secondes&lt;br /&gt;
| 900 secondes (15 minutes)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les rapports peuvent donc être calculés lors de leur consultation.&lt;br /&gt;
&lt;br /&gt;
Cette configuration convient à une installation de faible volume, notamment lors de la mise en service.&lt;br /&gt;
&lt;br /&gt;
Elle peut cependant provoquer des calculs au moment où un utilisateur consulte les statistiques.&lt;br /&gt;
&lt;br /&gt;
=== Méthode 2 : archivage automatique ===&lt;br /&gt;
&lt;br /&gt;
Pour une installation plus sollicitée, un archivage planifié est préférable.&lt;br /&gt;
&lt;br /&gt;
Matomo fournit la commande :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo -u www-data php /var/www/matomo/console core:archive&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; cette commande lance réellement l&#039;archivage. Ne pas l&#039;exécuter pour une simple vérification.&lt;br /&gt;
&lt;br /&gt;
Pour afficher les options sans lancer de traitement :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo -u www-data php /var/www/matomo/console core:archive --help&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemple de tâche cron ===&lt;br /&gt;
&lt;br /&gt;
Exemple de configuration pour un archivage toutes les heures :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cron&amp;quot;&amp;gt;&lt;br /&gt;
0 * * * * /usr/bin/php /var/www/matomo/console core:archive --url=https://matomo.exemple.fr/ &amp;gt;&amp;gt; /var/log/matomo-archive.log 2&amp;gt;&amp;amp;1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette ligne est un &#039;&#039;&#039;exemple de configuration&#039;&#039;&#039;, et non une tâche déjà installée sur AD64.&lt;br /&gt;
&lt;br /&gt;
Elle doit être adaptée avant utilisation :&lt;br /&gt;
&lt;br /&gt;
* À l&#039;URL réelle de Matomo.&lt;br /&gt;
* À l&#039;utilisateur d&#039;exécution PHP.&lt;br /&gt;
* Aux permissions du fichier journal.&lt;br /&gt;
* À la fréquence d&#039;archivage souhaitée.&lt;br /&gt;
* Aux restrictions réseau ou HAProxy.&lt;br /&gt;
&lt;br /&gt;
Le processus d&#039;archivage doit pouvoir joindre les ressources Matomo nécessaires. Une interface d&#039;administration protégée par HAProxy peut imposer une configuration particulière de l&#039;URL utilisée.&lt;br /&gt;
&lt;br /&gt;
=== Passage à l&#039;archivage automatique ===&lt;br /&gt;
&lt;br /&gt;
Avant de mettre en service une tâche planifiée :&lt;br /&gt;
&lt;br /&gt;
# Vérifier le bon fonctionnement de la commande `core:archive`.&lt;br /&gt;
# Vérifier que l&#039;URL utilisée est accessible depuis la VM.&lt;br /&gt;
# Configurer une tâche planifiée sous l&#039;utilisateur approprié.&lt;br /&gt;
# Vérifier les journaux d&#039;exécution.&lt;br /&gt;
# Contrôler que les rapports sont correctement actualisés.&lt;br /&gt;
# Désactiver ensuite l&#039;archivage déclenché par le navigateur dans les paramètres généraux de Matomo, conformément à la configuration retenue.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ne pas désactiver l&#039;archivage depuis le navigateur avant d&#039;avoir confirmé le fonctionnement de l&#039;archivage automatique.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== 5. Vérification de la collecte ==&lt;br /&gt;
&lt;br /&gt;
=== Tests HTTP ===&lt;br /&gt;
&lt;br /&gt;
Depuis une connexion extérieure au réseau AJLSM :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
MATOMO_URL=&amp;quot;https://matomo.exemple.fr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
for RESOURCE in matomo.js matomo.php; do&lt;br /&gt;
    echo &amp;quot;===== /$RESOURCE =====&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    curl -sS -o /dev/null -w &amp;quot;HTTP %{http_code}\n&amp;quot; \&lt;br /&gt;
      &amp;quot;$MATOMO_URL/$RESOURCE&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pour une installation utilisant les ACL HAProxy décrites dans [[Matomo/HAProxy]], les ressources de collecte doivent rester accessibles publiquement.&lt;br /&gt;
&lt;br /&gt;
=== Vérification en base ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT&lt;br /&gt;
    idsite,&lt;br /&gt;
    COUNT(*) AS visites,&lt;br /&gt;
    MAX(visit_last_action_time) AS derniere_activite&lt;br /&gt;
FROM matomo_log_visit&lt;br /&gt;
GROUP BY idsite;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La présence de visites récentes confirme que des données sont enregistrées.&lt;br /&gt;
&lt;br /&gt;
Cette requête ne permet cependant pas, à elle seule, de vérifier l&#039;exactitude de tous les rapports.&lt;br /&gt;
&lt;br /&gt;
=== Vérification depuis Drupal ===&lt;br /&gt;
&lt;br /&gt;
Consulter une page publique de l&#039;application Drupal suivie.&lt;br /&gt;
&lt;br /&gt;
Vérifier ensuite :&lt;br /&gt;
&lt;br /&gt;
* Que le script Matomo est chargé.&lt;br /&gt;
* Qu&#039;une requête de suivi est transmise.&lt;br /&gt;
* Qu&#039;aucune erreur de suivi n&#039;apparaît.&lt;br /&gt;
* Que la visite est enregistrée sur le bon identifiant de site Matomo.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Drupal]].&lt;br /&gt;
&lt;br /&gt;
== 6. Certificats et sécurité ==&lt;br /&gt;
&lt;br /&gt;
=== HTTPS ===&lt;br /&gt;
&lt;br /&gt;
Pour les installations publiées par HAProxy, le certificat public est généralement géré sur les répartiteurs.&lt;br /&gt;
&lt;br /&gt;
Vérifier la date d&#039;expiration :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
openssl s_client \&lt;br /&gt;
  -connect matomo.exemple.fr:443 \&lt;br /&gt;
  -servername matomo.exemple.fr &amp;lt;/dev/null 2&amp;gt;/dev/null \&lt;br /&gt;
  | openssl x509 -noout -subject -issuer -dates&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier également le renouvellement automatique et le déploiement effectif du certificat.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/HAProxy]].&lt;br /&gt;
&lt;br /&gt;
=== Restrictions d&#039;accès ===&lt;br /&gt;
&lt;br /&gt;
Lorsque l&#039;administration est réservée à AJLSM :&lt;br /&gt;
&lt;br /&gt;
* L&#039;interface Matomo doit être inaccessible depuis une IP extérieure non autorisée.&lt;br /&gt;
* Les points de collecte nécessaires doivent rester accessibles.&lt;br /&gt;
* L&#039;accès à l&#039;administration doit rester possible depuis le réseau autorisé.&lt;br /&gt;
&lt;br /&gt;
=== Permissions ===&lt;br /&gt;
&lt;br /&gt;
Vérifier périodiquement les permissions des fichiers sensibles :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
stat -c &#039;%A %a %U:%G %n&#039; \&lt;br /&gt;
  /var/www/matomo \&lt;br /&gt;
  /var/www/matomo/config/config.ini.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Installation]] pour les permissions recommandées.&lt;br /&gt;
&lt;br /&gt;
== 7. Journaux et diagnostic ==&lt;br /&gt;
&lt;br /&gt;
En cas de dysfonctionnement, consulter les journaux Apache :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo journalctl -u apache2 --since &amp;quot;1 hour ago&amp;quot; --no-pager&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les fichiers de logs Apache peuvent également être consultés dans `/var/log/apache2/`, selon la configuration du VirtualHost.&lt;br /&gt;
&lt;br /&gt;
Pour MariaDB :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo journalctl -u mariadb --since &amp;quot;1 hour ago&amp;quot; --no-pager&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier aussi les journaux et messages d&#039;erreur propres à Matomo.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Debug]].&lt;br /&gt;
&lt;br /&gt;
== 8. Retour d&#039;expérience AD64 — octobre 2026 ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Élément&lt;br /&gt;
! Situation constatée&lt;br /&gt;
|-&lt;br /&gt;
| Matomo&lt;br /&gt;
| Version 5.10.1&lt;br /&gt;
|-&lt;br /&gt;
| Serveur&lt;br /&gt;
| ad64&lt;br /&gt;
|-&lt;br /&gt;
| Répertoire&lt;br /&gt;
| /var/www/matomo&lt;br /&gt;
|-&lt;br /&gt;
| Serveur web&lt;br /&gt;
| Apache avec mod_php et mpm_prefork&lt;br /&gt;
|-&lt;br /&gt;
| Base de données&lt;br /&gt;
| MariaDB, base matomo&lt;br /&gt;
|-&lt;br /&gt;
| Taille de la base&lt;br /&gt;
| 5,70 Mo au 20 octobre 2026&lt;br /&gt;
|-&lt;br /&gt;
| Mise à jour Matomo&lt;br /&gt;
| Depuis l&#039;interface d&#039;administration&lt;br /&gt;
|-&lt;br /&gt;
| Archivage&lt;br /&gt;
| Déclenché depuis le navigateur&lt;br /&gt;
|-&lt;br /&gt;
| Fréquence d&#039;archivage configurée&lt;br /&gt;
| 900 secondes&lt;br /&gt;
|-&lt;br /&gt;
| Cron core:archive&lt;br /&gt;
| Aucune tâche identifiée dans les emplacements examinés&lt;br /&gt;
|-&lt;br /&gt;
| Sites suivis&lt;br /&gt;
| Drupal Internet et Salle de lecture&lt;br /&gt;
|-&lt;br /&gt;
| Administration&lt;br /&gt;
| Restreinte par HAProxy aux adresses AJLSM autorisées&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Points restant à vérifier ===&lt;br /&gt;
&lt;br /&gt;
* La couverture exacte de Matomo par les sauvegardes existantes.&lt;br /&gt;
* La présence éventuelle d&#039;une sauvegarde MariaDB indépendante.&lt;br /&gt;
* Le test de restauration.&lt;br /&gt;
* Le renouvellement effectif du certificat public lors de sa prochaine échéance.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Conclusion :&#039;&#039;&#039; AD64 fonctionne actuellement avec un archivage à la demande et des mises à jour réalisées depuis l&#039;interface Matomo. Il n&#039;est pas nécessaire de modifier immédiatement cette configuration. Pour les futures installations, les sauvegardes et l&#039;archivage automatique devront être évalués selon le volume et les exigences du projet.&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=Matomo/Maintenance&amp;diff=6519</id>
		<title>Matomo/Maintenance</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=Matomo/Maintenance&amp;diff=6519"/>
		<updated>2026-10-20T11:04:34Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : Page créée avec « = Maintenance de Matomo =  == Objectif ==  Cette procédure décrit la maintenance des installations Matomo hébergées sur les VM AJLSM.  Elle couvre :  * La surveillance... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Maintenance de Matomo =&lt;br /&gt;
&lt;br /&gt;
== Objectif ==&lt;br /&gt;
&lt;br /&gt;
Cette procédure décrit la maintenance des installations Matomo hébergées sur les VM AJLSM.&lt;br /&gt;
&lt;br /&gt;
Elle couvre :&lt;br /&gt;
&lt;br /&gt;
* La surveillance des services.&lt;br /&gt;
* Les mises à jour de Matomo.&lt;br /&gt;
* Les sauvegardes et la restauration.&lt;br /&gt;
* L&#039;archivage des statistiques.&lt;br /&gt;
* La vérification de la collecte.&lt;br /&gt;
* Les contrôles de sécurité.&lt;br /&gt;
&lt;br /&gt;
Voir également :&lt;br /&gt;
&lt;br /&gt;
* [[Matomo/Installation]]&lt;br /&gt;
* [[Matomo/Apache]]&lt;br /&gt;
* [[Matomo/Drupal]]&lt;br /&gt;
* [[Matomo/HAProxy]]&lt;br /&gt;
* [[Matomo/Debug]]&lt;br /&gt;
&lt;br /&gt;
== 1. Vérifications courantes ==&lt;br /&gt;
&lt;br /&gt;
=== Version de Matomo ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /var/www/matomo&lt;br /&gt;
sudo -u www-data php console core:version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Services Apache et MariaDB ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl is-active apache2&lt;br /&gt;
systemctl is-active mariadb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Si la VM utilise PHP-FPM, vérifier également le service correspondant :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl is-active php8.4-fpm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; PHP-FPM n&#039;est pas nécessaire lorsque PHP est exécuté par Apache avec `mod_php`, comme sur AD64.&lt;br /&gt;
&lt;br /&gt;
=== Espace disque ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
df -h&lt;br /&gt;
du -sh /var/www/matomo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Taille de la base Matomo ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo mariadb -t -e &amp;quot;&lt;br /&gt;
SELECT&lt;br /&gt;
    table_schema AS base,&lt;br /&gt;
    ROUND(SUM(data_length + index_length)/1024/1024, 2) AS taille_Mo&lt;br /&gt;
FROM information_schema.tables&lt;br /&gt;
WHERE table_schema = &#039;matomo&#039;&lt;br /&gt;
GROUP BY table_schema;&lt;br /&gt;
&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La taille de la base doit être surveillée, notamment lorsque le nombre de visites et la durée de conservation des données augmentent.&lt;br /&gt;
&lt;br /&gt;
== 2. Mise à jour de Matomo ==&lt;br /&gt;
&lt;br /&gt;
=== Méthode habituelle AJLSM ===&lt;br /&gt;
&lt;br /&gt;
Les mises à jour de Matomo sont proposées directement dans son interface d&#039;administration.&lt;br /&gt;
&lt;br /&gt;
Sur AD64, les précédentes mises à jour ont été réalisées depuis cette interface, sans passer par le terminal.&lt;br /&gt;
&lt;br /&gt;
Cette méthode est retenue comme procédure habituelle.&lt;br /&gt;
&lt;br /&gt;
=== Avant la mise à jour ===&lt;br /&gt;
&lt;br /&gt;
# Vérifier la compatibilité de la nouvelle version avec PHP et MariaDB.&lt;br /&gt;
# Vérifier l&#039;espace disque disponible.&lt;br /&gt;
# Effectuer une sauvegarde de la base MariaDB.&lt;br /&gt;
# Sauvegarder les fichiers de configuration et les éventuels plugins personnalisés.&lt;br /&gt;
# Vérifier que les sauvegardes sont exploitables.&lt;br /&gt;
&lt;br /&gt;
Exemple de sauvegarde manuelle de la base :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo mariadb-dump --single-transaction \&lt;br /&gt;
  --routines --triggers --events \&lt;br /&gt;
  matomo &amp;gt; &amp;quot;$HOME/matomo-$(date +%Y%m%d-%H%M%S).sql&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; cette commande crée une sauvegarde ponctuelle dans le répertoire personnel de l&#039;utilisateur courant. Elle ne remplace pas la stratégie de sauvegarde générale de la VM.&lt;br /&gt;
&lt;br /&gt;
Vérifier également les sauvegardes existantes avant toute intervention importante.&lt;br /&gt;
&lt;br /&gt;
=== Effectuer la mise à jour ===&lt;br /&gt;
&lt;br /&gt;
# Se connecter à l&#039;administration Matomo depuis une adresse IP autorisée.&lt;br /&gt;
# Ouvrir la notification de nouvelle version.&lt;br /&gt;
# Lire les informations et les prérequis.&lt;br /&gt;
# Lancer la mise à jour depuis l&#039;interface.&lt;br /&gt;
# Effectuer, si demandé, la mise à jour de la base de données.&lt;br /&gt;
# Attendre la confirmation de fin d&#039;opération.&lt;br /&gt;
&lt;br /&gt;
Ne pas interrompre une mise à jour en cours.&lt;br /&gt;
&lt;br /&gt;
=== Après la mise à jour ===&lt;br /&gt;
&lt;br /&gt;
Vérifier :&lt;br /&gt;
&lt;br /&gt;
* La version affichée par Matomo.&lt;br /&gt;
* L&#039;accès à l&#039;interface d&#039;administration.&lt;br /&gt;
* L&#039;absence d&#039;erreurs dans les journaux.&lt;br /&gt;
* Le fonctionnement des rapports.&lt;br /&gt;
* La réception de nouvelles visites.&lt;br /&gt;
* Le fonctionnement des plugins installés.&lt;br /&gt;
&lt;br /&gt;
Commande de vérification :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /var/www/matomo&lt;br /&gt;
sudo -u www-data php console core:version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3. Sauvegardes ==&lt;br /&gt;
&lt;br /&gt;
=== Éléments à sauvegarder ===&lt;br /&gt;
&lt;br /&gt;
Une sauvegarde exploitable doit couvrir :&lt;br /&gt;
&lt;br /&gt;
* La base MariaDB `matomo`.&lt;br /&gt;
* Le fichier `/var/www/matomo/config/config.ini.php`.&lt;br /&gt;
* Les plugins ou personnalisations non fournis par l&#039;installation standard.&lt;br /&gt;
* Les autres fichiers spécifiques à l&#039;installation, s&#039;il en existe.&lt;br /&gt;
&lt;br /&gt;
Le code standard de Matomo peut être réinstallé, mais la base de données et la configuration sont indispensables à la restitution de l&#039;installation.&lt;br /&gt;
&lt;br /&gt;
=== Sauvegarde de la base ===&lt;br /&gt;
&lt;br /&gt;
Exemple de sauvegarde compressée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo mariadb-dump --single-transaction \&lt;br /&gt;
  --routines --triggers --events \&lt;br /&gt;
  matomo | gzip &amp;gt; &amp;quot;$HOME/matomo-$(date +%Y%m%d-%H%M%S).sql.gz&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Protéger les sauvegardes : elles peuvent contenir des informations sur les visiteurs et des données de configuration sensibles.&lt;br /&gt;
&lt;br /&gt;
=== Sauvegarde de la configuration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo tar -czf &amp;quot;$HOME/matomo-config-$(date +%Y%m%d-%H%M%S).tar.gz&amp;quot; \&lt;br /&gt;
  -C /var/www/matomo \&lt;br /&gt;
  config&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les archives doivent être conservées dans un emplacement protégé, idéalement distinct de la VM.&lt;br /&gt;
&lt;br /&gt;
=== Sauvegardes de l&#039;infrastructure ===&lt;br /&gt;
&lt;br /&gt;
Avant d&#039;ajouter une sauvegarde spécifique, vérifier si Matomo est déjà couvert par :&lt;br /&gt;
&lt;br /&gt;
* Les sauvegardes de la VM Proxmox.&lt;br /&gt;
* Les sauvegardes applicatives existantes.&lt;br /&gt;
* Les sauvegardes MariaDB éventuellement configurées sur la VM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; la présence d&#039;une sauvegarde ne garantit pas sa restaurabilité. Un test de restauration doit être prévu.&lt;br /&gt;
&lt;br /&gt;
=== Restauration ===&lt;br /&gt;
&lt;br /&gt;
Une restauration doit être préparée en fonction de l&#039;incident.&lt;br /&gt;
&lt;br /&gt;
La procédure générale consiste à :&lt;br /&gt;
&lt;br /&gt;
# Préserver l&#039;état actuel avant toute intervention.&lt;br /&gt;
# Identifier une sauvegarde cohérente de la base et des fichiers.&lt;br /&gt;
# Restaurer dans un environnement de test lorsque cela est possible.&lt;br /&gt;
# Vérifier la compatibilité entre la version du code Matomo et le schéma de la base restaurée.&lt;br /&gt;
# Restaurer les données et la configuration.&lt;br /&gt;
# Vérifier les permissions.&lt;br /&gt;
# Tester l&#039;interface et la collecte.&lt;br /&gt;
&lt;br /&gt;
Ne pas restaurer directement une ancienne base sur une installation Matomo plus récente sans avoir vérifié la compatibilité.&lt;br /&gt;
&lt;br /&gt;
== 4. Archivage des statistiques ==&lt;br /&gt;
&lt;br /&gt;
=== Principe ===&lt;br /&gt;
&lt;br /&gt;
Matomo calcule des rapports statistiques à partir des données de visites.&lt;br /&gt;
&lt;br /&gt;
Deux méthodes principales sont possibles :&lt;br /&gt;
&lt;br /&gt;
* Archivage déclenché par la consultation des rapports dans le navigateur.&lt;br /&gt;
* Archivage automatique par une tâche planifiée exécutant `core:archive`.&lt;br /&gt;
&lt;br /&gt;
=== Méthode 1 : archivage depuis le navigateur ===&lt;br /&gt;
&lt;br /&gt;
Cette méthode est utilisée sur AD64 en octobre 2026.&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;administration Matomo :&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Administration → Système → Paramètres généraux → Paramètres d&#039;archivage&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Configuration constatée :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Paramètre&lt;br /&gt;
! Valeur AD64&lt;br /&gt;
|-&lt;br /&gt;
| Archiver les rapports lorsqu&#039;ils sont affichés depuis le navigateur&lt;br /&gt;
| Oui&lt;br /&gt;
|-&lt;br /&gt;
| Archiver les rapports au plus toutes les X secondes&lt;br /&gt;
| 900 secondes (15 minutes)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les rapports peuvent donc être calculés lors de leur consultation.&lt;br /&gt;
&lt;br /&gt;
Cette configuration convient à une installation de faible volume, notamment lors de la mise en service.&lt;br /&gt;
&lt;br /&gt;
Elle peut cependant provoquer des calculs au moment où un utilisateur consulte les statistiques.&lt;br /&gt;
&lt;br /&gt;
=== Méthode 2 : archivage automatique ===&lt;br /&gt;
&lt;br /&gt;
Pour une installation plus sollicitée, un archivage planifié est préférable.&lt;br /&gt;
&lt;br /&gt;
Matomo fournit la commande :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo -u www-data php /var/www/matomo/console core:archive&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; cette commande lance réellement l&#039;archivage. Ne pas l&#039;exécuter pour une simple vérification.&lt;br /&gt;
&lt;br /&gt;
Pour afficher les options sans lancer de traitement :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo -u www-data php /var/www/matomo/console core:archive --help&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemple de tâche cron ===&lt;br /&gt;
&lt;br /&gt;
Exemple de configuration pour un archivage toutes les heures :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cron&amp;quot;&amp;gt;&lt;br /&gt;
0 * * * * /usr/bin/php /var/www/matomo/console core:archive --url=https://matomo.exemple.fr/ &amp;gt;&amp;gt; /var/log/matomo-archive.log 2&amp;gt;&amp;amp;1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette ligne est un &#039;&#039;&#039;exemple de configuration&#039;&#039;&#039;, et non une tâche déjà installée sur AD64.&lt;br /&gt;
&lt;br /&gt;
Elle doit être adaptée avant utilisation :&lt;br /&gt;
&lt;br /&gt;
* À l&#039;URL réelle de Matomo.&lt;br /&gt;
* À l&#039;utilisateur d&#039;exécution PHP.&lt;br /&gt;
* Aux permissions du fichier journal.&lt;br /&gt;
* À la fréquence d&#039;archivage souhaitée.&lt;br /&gt;
* Aux restrictions réseau ou HAProxy.&lt;br /&gt;
&lt;br /&gt;
Le processus d&#039;archivage doit pouvoir joindre les ressources Matomo nécessaires. Une interface d&#039;administration protégée par HAProxy peut imposer une configuration particulière de l&#039;URL utilisée.&lt;br /&gt;
&lt;br /&gt;
=== Passage à l&#039;archivage automatique ===&lt;br /&gt;
&lt;br /&gt;
Avant de mettre en service une tâche planifiée :&lt;br /&gt;
&lt;br /&gt;
# Vérifier le bon fonctionnement de la commande `core:archive`.&lt;br /&gt;
# Vérifier que l&#039;URL utilisée est accessible depuis la VM.&lt;br /&gt;
# Configurer une tâche planifiée sous l&#039;utilisateur approprié.&lt;br /&gt;
# Vérifier les journaux d&#039;exécution.&lt;br /&gt;
# Contrôler que les rapports sont correctement actualisés.&lt;br /&gt;
# Désactiver ensuite l&#039;archivage déclenché par le navigateur dans les paramètres généraux de Matomo, conformément à la configuration retenue.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ne pas désactiver l&#039;archivage depuis le navigateur avant d&#039;avoir confirmé le fonctionnement de l&#039;archivage automatique.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== 5. Vérification de la collecte ==&lt;br /&gt;
&lt;br /&gt;
=== Tests HTTP ===&lt;br /&gt;
&lt;br /&gt;
Depuis une connexion extérieure au réseau AJLSM :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
MATOMO_URL=&amp;quot;https://matomo.exemple.fr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
for RESOURCE in matomo.js matomo.php; do&lt;br /&gt;
    echo &amp;quot;===== /$RESOURCE =====&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    curl -sS -o /dev/null -w &amp;quot;HTTP %{http_code}\n&amp;quot; \&lt;br /&gt;
      &amp;quot;$MATOMO_URL/$RESOURCE&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pour une installation utilisant les ACL HAProxy décrites dans [[Matomo/HAProxy]], les ressources de collecte doivent rester accessibles publiquement.&lt;br /&gt;
&lt;br /&gt;
=== Vérification en base ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT&lt;br /&gt;
    idsite,&lt;br /&gt;
    COUNT(*) AS visites,&lt;br /&gt;
    MAX(visit_last_action_time) AS derniere_activite&lt;br /&gt;
FROM matomo_log_visit&lt;br /&gt;
GROUP BY idsite;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La présence de visites récentes confirme que des données sont enregistrées.&lt;br /&gt;
&lt;br /&gt;
Cette requête ne permet cependant pas, à elle seule, de vérifier l&#039;exactitude de tous les rapports.&lt;br /&gt;
&lt;br /&gt;
=== Vérification depuis Drupal ===&lt;br /&gt;
&lt;br /&gt;
Consulter une page publique de l&#039;application Drupal suivie.&lt;br /&gt;
&lt;br /&gt;
Vérifier ensuite :&lt;br /&gt;
&lt;br /&gt;
* Que le script Matomo est chargé.&lt;br /&gt;
* Qu&#039;une requête de suivi est transmise.&lt;br /&gt;
* Qu&#039;aucune erreur de suivi n&#039;apparaît.&lt;br /&gt;
* Que la visite est enregistrée sur le bon identifiant de site Matomo.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Drupal]].&lt;br /&gt;
&lt;br /&gt;
== 6. Certificats et sécurité ==&lt;br /&gt;
&lt;br /&gt;
=== HTTPS ===&lt;br /&gt;
&lt;br /&gt;
Pour les installations publiées par HAProxy, le certificat public est généralement géré sur les répartiteurs.&lt;br /&gt;
&lt;br /&gt;
Vérifier la date d&#039;expiration :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
openssl s_client \&lt;br /&gt;
  -connect matomo.exemple.fr:443 \&lt;br /&gt;
  -servername matomo.exemple.fr &amp;lt;/dev/null 2&amp;gt;/dev/null \&lt;br /&gt;
  | openssl x509 -noout -subject -issuer -dates&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier également le renouvellement automatique et le déploiement effectif du certificat.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/HAProxy]].&lt;br /&gt;
&lt;br /&gt;
=== Restrictions d&#039;accès ===&lt;br /&gt;
&lt;br /&gt;
Lorsque l&#039;administration est réservée à AJLSM :&lt;br /&gt;
&lt;br /&gt;
* L&#039;interface Matomo doit être inaccessible depuis une IP extérieure non autorisée.&lt;br /&gt;
* Les points de collecte nécessaires doivent rester accessibles.&lt;br /&gt;
* L&#039;accès à l&#039;administration doit rester possible depuis le réseau autorisé.&lt;br /&gt;
&lt;br /&gt;
=== Permissions ===&lt;br /&gt;
&lt;br /&gt;
Vérifier périodiquement les permissions des fichiers sensibles :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
stat -c &#039;%A %a %U:%G %n&#039; \&lt;br /&gt;
  /var/www/matomo \&lt;br /&gt;
  /var/www/matomo/config/config.ini.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Installation]] pour les permissions recommandées.&lt;br /&gt;
&lt;br /&gt;
== 7. Journaux et diagnostic ==&lt;br /&gt;
&lt;br /&gt;
En cas de dysfonctionnement, consulter les journaux Apache :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo journalctl -u apache2 --since &amp;quot;1 hour ago&amp;quot; --no-pager&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les fichiers de logs Apache peuvent également être consultés dans `/var/log/apache2/`, selon la configuration du VirtualHost.&lt;br /&gt;
&lt;br /&gt;
Pour MariaDB :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo journalctl -u mariadb --since &amp;quot;1 hour ago&amp;quot; --no-pager&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier aussi les journaux et messages d&#039;erreur propres à Matomo.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Debug]].&lt;br /&gt;
&lt;br /&gt;
== 8. Retour d&#039;expérience AD64 — octobre 2026 ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Élément&lt;br /&gt;
! Situation constatée&lt;br /&gt;
|-&lt;br /&gt;
| Matomo&lt;br /&gt;
| Version 5.10.1&lt;br /&gt;
|-&lt;br /&gt;
| Serveur&lt;br /&gt;
| ad64&lt;br /&gt;
|-&lt;br /&gt;
| Répertoire&lt;br /&gt;
| /var/www/matomo&lt;br /&gt;
|-&lt;br /&gt;
| Serveur web&lt;br /&gt;
| Apache avec mod_php et mpm_prefork&lt;br /&gt;
|-&lt;br /&gt;
| Base de données&lt;br /&gt;
| MariaDB, base matomo&lt;br /&gt;
|-&lt;br /&gt;
| Taille de la base&lt;br /&gt;
| 5,70 Mo au 20 octobre 2026&lt;br /&gt;
|-&lt;br /&gt;
| Mise à jour Matomo&lt;br /&gt;
| Depuis l&#039;interface d&#039;administration&lt;br /&gt;
|-&lt;br /&gt;
| Archivage&lt;br /&gt;
| Déclenché depuis le navigateur&lt;br /&gt;
|-&lt;br /&gt;
| Fréquence d&#039;archivage configurée&lt;br /&gt;
| 900 secondes&lt;br /&gt;
|-&lt;br /&gt;
| Cron core:archive&lt;br /&gt;
| Aucune tâche identifiée dans les emplacements examinés&lt;br /&gt;
|-&lt;br /&gt;
| Sites suivis&lt;br /&gt;
| Drupal Internet et Salle de lecture&lt;br /&gt;
|-&lt;br /&gt;
| Administration&lt;br /&gt;
| Restreinte par HAProxy aux adresses AJLSM autorisées&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Points restant à vérifier ===&lt;br /&gt;
&lt;br /&gt;
* La couverture exacte de Matomo par les sauvegardes existantes.&lt;br /&gt;
* La présence éventuelle d&#039;une sauvegarde MariaDB indépendante.&lt;br /&gt;
* Le test de restauration.&lt;br /&gt;
* Le renouvellement effectif du certificat public lors de sa prochaine échéance.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Conclusion :&#039;&#039;&#039; AD64 fonctionne actuellement avec un archivage à la demande et des mises à jour réalisées depuis l&#039;interface Matomo. Il n&#039;est pas nécessaire de modifier immédiatement cette configuration. Pour les futures installations, les sauvegardes et l&#039;archivage automatique devront être évalués selon le volume et les exigences du projet.&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=Matomo/Installation&amp;diff=6518</id>
		<title>Matomo/Installation</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=Matomo/Installation&amp;diff=6518"/>
		<updated>2026-10-20T10:56:09Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : /* 1. Environnement technique */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Installation de Matomo sur une VM Ubuntu =&lt;br /&gt;
&lt;br /&gt;
== Objectif ==&lt;br /&gt;
&lt;br /&gt;
Cette procédure décrit l&#039;installation de Matomo sur les VM AJLSM hébergeant les applications Pleade et Drupal.&lt;br /&gt;
&lt;br /&gt;
Elle est destinée à être réutilisée pour les nouveaux projets, indépendamment du client et du nom de domaine.&lt;br /&gt;
&lt;br /&gt;
La configuration Apache, l&#039;intégration Drupal et la publication sécurisée par HAProxy sont détaillées dans des chapitres distincts :&lt;br /&gt;
&lt;br /&gt;
* [[Matomo/Apache]]&lt;br /&gt;
* [[Matomo/Drupal]]&lt;br /&gt;
* [[Matomo/HAProxy]]&lt;br /&gt;
* [[Matomo/Maintenance]]&lt;br /&gt;
&lt;br /&gt;
== 1. Environnement technique ==&lt;br /&gt;
&lt;br /&gt;
Matomo fonctionne avec Apache 2.4, PHP et MariaDB/MySQL.&lt;br /&gt;
&lt;br /&gt;
Deux modes d&#039;exécution de PHP sont possibles :&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;mod_php&#039;&#039;&#039; : PHP est exécuté directement par Apache.&lt;br /&gt;
* &#039;&#039;&#039;PHP-FPM&#039;&#039;&#039; : PHP est exécuté par un service indépendant auquel Apache transmet les requêtes PHP.&lt;br /&gt;
&lt;br /&gt;
Le choix dépend de la configuration de la VM. Il n&#039;est pas nécessaire d&#039;installer PHP-FPM lorsque Matomo fonctionne déjà avec mod_php.&lt;br /&gt;
&lt;br /&gt;
=== Versions PHP ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Ubuntu&lt;br /&gt;
! Version PHP de référence&lt;br /&gt;
! Observations&lt;br /&gt;
|-&lt;br /&gt;
| Ubuntu 18.04&lt;br /&gt;
| PHP 8.1&lt;br /&gt;
| Installation historique avec version PHP ajoutée séparément&lt;br /&gt;
|-&lt;br /&gt;
| Ubuntu 24.04&lt;br /&gt;
| PHP 8.3&lt;br /&gt;
| Version fournie par Ubuntu&lt;br /&gt;
|-&lt;br /&gt;
| Ubuntu 26.04&lt;br /&gt;
| PHP 8.4&lt;br /&gt;
| Version utilisée sur AD64 en octobre 2026&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Vérifier systématiquement la compatibilité entre PHP et la version de Matomo installée.&lt;br /&gt;
&lt;br /&gt;
=== Composants nécessaires ===&lt;br /&gt;
&lt;br /&gt;
* Apache 2.4&lt;br /&gt;
* PHP avec &#039;&#039;&#039;mod_php&#039;&#039;&#039; ou &#039;&#039;&#039;PHP-FPM&#039;&#039;&#039;&lt;br /&gt;
* MariaDB ou MySQL&lt;br /&gt;
* Extensions PHP requises par Matomo&lt;br /&gt;
* Accès HTTPS, directement ou via HAProxy&lt;br /&gt;
* Accès réseau permettant le téléchargement et les mises à jour de Matomo&lt;br /&gt;
&lt;br /&gt;
== 2. Installation des dépendances PHP ==&lt;br /&gt;
&lt;br /&gt;
Adapter la version de PHP à celle installée sur la VM.&lt;br /&gt;
&lt;br /&gt;
=== Ubuntu 24.04 — PHP 8.3 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install \&lt;br /&gt;
  php8.3-mysql php8.3-gd php8.3-curl php8.3-xml \&lt;br /&gt;
  php8.3-mbstring php8.3-zip php8.3-intl&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ubuntu 26.04 — PHP 8.4 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install \&lt;br /&gt;
  php8.4-mysql php8.4-gd php8.4-curl php8.4-xml \&lt;br /&gt;
  php8.4-mbstring php8.4-zip php8.4-intl&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Vérification ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php -v&lt;br /&gt;
php -m | grep -Ei &#039;mysqli|pdo_mysql|gd|curl|mbstring|xml|zip|intl&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3. Configuration PHP avec Apache ==&lt;br /&gt;
&lt;br /&gt;
=== Identifier le mode PHP utilisé ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apache2ctl -M 2&amp;gt;/dev/null | grep -E &#039;php_module|proxy_fcgi_module|mpm_&#039;&lt;br /&gt;
&lt;br /&gt;
systemctl list-units --all &#039;php*-fpm.service&#039; --no-pager&lt;br /&gt;
&lt;br /&gt;
php -v&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; la présence du module proxy_fcgi_module ne signifie pas nécessairement que PHP-FPM est utilisé. Il faut également vérifier les VirtualHosts et les gestionnaires PHP configurés.&lt;br /&gt;
&lt;br /&gt;
=== Cas 1 : Apache avec mod_php ===&lt;br /&gt;
&lt;br /&gt;
Dans cette configuration, PHP est exécuté directement par Apache.&lt;br /&gt;
&lt;br /&gt;
Exemple observé sur AD64 :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
mpm_prefork_module (shared)&lt;br /&gt;
php_module (shared)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aucun service PHP-FPM n&#039;est nécessaire.&lt;br /&gt;
&lt;br /&gt;
Vérifier qu&#039;Apache fonctionne :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl is-active apache2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pour une nouvelle installation utilisant ce mode, installer le module Apache correspondant à la version PHP disponible, par exemple :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install libapache2-mod-php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ne pas modifier le mode d&#039;exécution PHP d&#039;une VM existante sans vérifier les autres applications hébergées.&lt;br /&gt;
&lt;br /&gt;
=== Cas 2 : Apache avec PHP-FPM ===&lt;br /&gt;
&lt;br /&gt;
PHP-FPM est une autre architecture possible, notamment lorsqu&#039;une VM utilise plusieurs pools PHP.&lt;br /&gt;
&lt;br /&gt;
Exemple avec PHP 8.4 :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install php8.4-fpm&lt;br /&gt;
&lt;br /&gt;
sudo a2enmod proxy_fcgi setenvif&lt;br /&gt;
sudo a2enconf php8.4-fpm&lt;br /&gt;
&lt;br /&gt;
sudo apache2ctl configtest&lt;br /&gt;
sudo systemctl reload apache2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier ensuite :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl is-active php8.4-fpm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; si plusieurs applications utilisent différentes versions de PHP, privilégier une configuration explicite par VirtualHost ou par pool plutôt que l&#039;activation systématique d&#039;une configuration globale.&lt;br /&gt;
&lt;br /&gt;
=== Retour d&#039;expérience AD64 — octobre 2026 ===&lt;br /&gt;
&lt;br /&gt;
L&#039;installation Matomo 5.10.1 sur AD64 utilise :&lt;br /&gt;
&lt;br /&gt;
Apache 2.4&lt;br /&gt;
&lt;br /&gt;
PHP 8.4&lt;br /&gt;
&lt;br /&gt;
mod_php&lt;br /&gt;
&lt;br /&gt;
mpm_prefork&lt;br /&gt;
&lt;br /&gt;
MariaDB&lt;br /&gt;
&lt;br /&gt;
Aucun service PHP-FPM n&#039;est actif.&lt;br /&gt;
&lt;br /&gt;
Cette configuration est fonctionnelle et ne nécessite aucune modification.&lt;br /&gt;
&lt;br /&gt;
== 4. Préparation de MariaDB ==&lt;br /&gt;
&lt;br /&gt;
Vérifier que MariaDB est installé et actif :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl status mariadb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Matomo nécessite :&lt;br /&gt;
&lt;br /&gt;
* Une base de données dédiée&lt;br /&gt;
* Un utilisateur SQL dédié&lt;br /&gt;
* Des droits limités à cette base&lt;br /&gt;
&lt;br /&gt;
Exemple générique à adapter :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
CREATE DATABASE matomo&lt;br /&gt;
  CHARACTER SET utf8mb4&lt;br /&gt;
  COLLATE utf8mb4_unicode_ci;&lt;br /&gt;
&lt;br /&gt;
CREATE USER &#039;matomo&#039;@&#039;localhost&#039;&lt;br /&gt;
  IDENTIFIED BY &#039;MOT_DE_PASSE_FORT_A_REMPLACER&#039;;&lt;br /&gt;
&lt;br /&gt;
GRANT ALL PRIVILEGES ON matomo.*&lt;br /&gt;
  TO &#039;matomo&#039;@&#039;localhost&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ne jamais conserver le mot de passe d&#039;exemple dans une installation réelle.&lt;br /&gt;
&lt;br /&gt;
== 5. Permissions et sécurisation des fichiers Matomo ==&lt;br /&gt;
&lt;br /&gt;
=== Principes ===&lt;br /&gt;
&lt;br /&gt;
L&#039;installation Matomo est située dans :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/var/www/matomo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sur les VM AJLSM, lorsque PHP-FPM s&#039;exécute sous l&#039;utilisateur `www-data`, les fichiers de Matomo appartiennent normalement à `www-data:www-data`.&lt;br /&gt;
&lt;br /&gt;
Les permissions de référence sont :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Élément&lt;br /&gt;
! Permissions&lt;br /&gt;
! Observations&lt;br /&gt;
|-&lt;br /&gt;
| Répertoires de l&#039;application&lt;br /&gt;
| 755&lt;br /&gt;
| Lecture et traversée autorisées ; écriture réservée au propriétaire&lt;br /&gt;
|-&lt;br /&gt;
| Fichiers de l&#039;application&lt;br /&gt;
| 644&lt;br /&gt;
| Lecture autorisée ; écriture réservée au propriétaire&lt;br /&gt;
|-&lt;br /&gt;
| config/config.ini.php&lt;br /&gt;
| 600&lt;br /&gt;
| Fichier sensible contenant notamment les paramètres de connexion à MariaDB&lt;br /&gt;
|-&lt;br /&gt;
| Répertoires temporaires et de configuration&lt;br /&gt;
| 755&lt;br /&gt;
| Accessibles en écriture au compte PHP-FPM lorsqu&#039;il en est propriétaire&lt;br /&gt;
|-&lt;br /&gt;
| .well-known/acme-challenge&lt;br /&gt;
| 755&lt;br /&gt;
| Peut appartenir à root:root ; ne pas modifier sans vérifier la configuration ACME&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; les permissions 755 et 644 ne rendent pas les fichiers accessibles en écriture à tous. Elles permettent uniquement au propriétaire de les modifier.&lt;br /&gt;
&lt;br /&gt;
=== Configuration initiale ===&lt;br /&gt;
&lt;br /&gt;
Pour une nouvelle installation dont l&#039;ensemble des fichiers applicatifs doit appartenir à `www-data` :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo chown -R www-data:www-data /var/www/matomo&lt;br /&gt;
&lt;br /&gt;
sudo find /var/www/matomo -type d -exec chmod 755 {} \;&lt;br /&gt;
sudo find /var/www/matomo -type f -exec chmod 644 {} \;&lt;br /&gt;
&lt;br /&gt;
sudo chmod 600 /var/www/matomo/config/config.ini.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; ces commandes concernent une installation initiale, avant la création éventuelle de répertoires spécifiques par d&#039;autres services. Ne pas les réexécuter aveuglément sur une installation existante.&lt;br /&gt;
&lt;br /&gt;
Vérifier préalablement le compte utilisé par PHP-FPM. Si celui-ci est différent de `www-data`, adapter les propriétaires et permissions.&lt;br /&gt;
&lt;br /&gt;
=== Vérification des permissions ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
stat -c &#039;%A %a %U:%G %n&#039; \&lt;br /&gt;
  /var/www/matomo \&lt;br /&gt;
  /var/www/matomo/config \&lt;br /&gt;
  /var/www/matomo/config/config.ini.php \&lt;br /&gt;
  /var/www/matomo/tmp \&lt;br /&gt;
  /var/www/matomo/plugins \&lt;br /&gt;
  /var/www/matomo/matomo.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier la répartition des propriétaires :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo find /var/www/matomo -xdev -printf &#039;%u:%g\n&#039; \&lt;br /&gt;
  | sort | uniq -c | sort -nr&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identifier les fichiers ou répertoires accessibles en écriture à tous :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo find /var/www/matomo -xdev -perm -0002 \&lt;br /&gt;
  -printf &#039;%m %u:%g %p\n&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette dernière commande ne doit normalement rien retourner.&lt;br /&gt;
&lt;br /&gt;
=== Vérification des répertoires accessibles en écriture ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for DIR in config tmp plugins; do&lt;br /&gt;
  if sudo -u www-data test -w &amp;quot;/var/www/matomo/$DIR&amp;quot;; then&lt;br /&gt;
    echo &amp;quot;$DIR : écriture OK&amp;quot;&lt;br /&gt;
  else&lt;br /&gt;
    echo &amp;quot;$DIR : écriture NON autorisée&amp;quot;&lt;br /&gt;
  fi&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Adapter `www-data` si Matomo utilise un autre compte PHP-FPM.&lt;br /&gt;
&lt;br /&gt;
=== Cas particulier des répertoires ACME ===&lt;br /&gt;
&lt;br /&gt;
Certains répertoires peuvent être créés et administrés par le mécanisme de validation des certificats Let&#039;s Encrypt :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/var/www/matomo/.well-known&lt;br /&gt;
/var/www/matomo/.well-known/acme-challenge&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ils peuvent légitimement appartenir à `root:root` avec des permissions `755`.&lt;br /&gt;
&lt;br /&gt;
Ne pas modifier systématiquement leur propriétaire : vérifier au préalable le mécanisme de validation ACME utilisé sur la VM.&lt;br /&gt;
&lt;br /&gt;
=== Vérification après modification ===&lt;br /&gt;
&lt;br /&gt;
Après toute modification des permissions :&lt;br /&gt;
&lt;br /&gt;
* Vérifier que l&#039;interface Matomo reste accessible.&lt;br /&gt;
* Vérifier que la connexion à MariaDB fonctionne.&lt;br /&gt;
* Vérifier qu&#039;aucune erreur de permission n&#039;apparaît dans les journaux Apache/PHP-FPM.&lt;br /&gt;
* Vérifier que les statistiques continuent à être collectées.&lt;br /&gt;
&lt;br /&gt;
=== Retour d&#039;expérience — AD64, octobre 2026 ===&lt;br /&gt;
&lt;br /&gt;
L&#039;audit de `/var/www/matomo` sur AD64 a donné les résultats suivants :&lt;br /&gt;
&lt;br /&gt;
* 13 315 éléments appartenant à `www-data:www-data`.&lt;br /&gt;
* 2 répertoires appartenant à `root:root` : `.well-known` et `.well-known/acme-challenge`.&lt;br /&gt;
* Répertoires `config`, `tmp` et `plugins` accessibles en écriture à `www-data`.&lt;br /&gt;
* Aucun fichier ou répertoire accessible en écriture à tous.&lt;br /&gt;
* Fichier `config/config.ini.php` initialement en `644` : passage recommandé en `600`.&lt;br /&gt;
* Interface Matomo vérifiée fonctionnelle.&lt;br /&gt;
&lt;br /&gt;
Aucune autre modification des propriétaires ou des permissions n&#039;était nécessaire.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Conclusion :&#039;&#039;&#039; pour les nouvelles installations, appliquer des permissions adaptées dès le départ et réserver l&#039;accès aux fichiers sensibles. Sur les installations existantes, effectuer un audit avant toute modification globale.&lt;br /&gt;
&lt;br /&gt;
== 6. Configuration Apache et HTTPS ==&lt;br /&gt;
&lt;br /&gt;
La configuration du VirtualHost Matomo est décrite dans :&lt;br /&gt;
&lt;br /&gt;
[[Matomo/Apache]]&lt;br /&gt;
&lt;br /&gt;
Deux architectures sont possibles :&lt;br /&gt;
&lt;br /&gt;
* Apache assure directement la terminaison HTTPS.&lt;br /&gt;
* HAProxy assure la terminaison HTTPS et transmet les requêtes à Apache.&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;infrastructure AJLSM utilisant HAProxy, le certificat public est généralement géré sur les répartiteurs de charge.&lt;br /&gt;
&lt;br /&gt;
La procédure de configuration des certificats et des ACL est décrite dans :&lt;br /&gt;
&lt;br /&gt;
[[Matomo/HAProxy]]&lt;br /&gt;
&lt;br /&gt;
Pour une installation utilisant directement Certbot sur Apache :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install certbot python3-certbot-apache&lt;br /&gt;
sudo certbot --apache&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette procédure Certbot ne doit pas être appliquée automatiquement à une VM dont le HTTPS public est déjà géré par HAProxy.&lt;br /&gt;
&lt;br /&gt;
== 7. Initialisation de Matomo ==&lt;br /&gt;
&lt;br /&gt;
Après configuration du VirtualHost, ouvrir dans un navigateur l&#039;URL HTTPS prévue pour Matomo.&lt;br /&gt;
&lt;br /&gt;
L&#039;assistant d&#039;installation permet notamment de :&lt;br /&gt;
&lt;br /&gt;
# Vérifier les prérequis système&lt;br /&gt;
# Configurer la connexion à MariaDB&lt;br /&gt;
# Initialiser les tables Matomo&lt;br /&gt;
# Créer le compte administrateur&lt;br /&gt;
# Déclarer le premier site suivi&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; chaque application suivie doit disposer de son propre identifiant de site Matomo lorsque l&#039;on souhaite séparer ses statistiques.&lt;br /&gt;
&lt;br /&gt;
Exemple : une application Internet et une salle de lecture Drupal peuvent être déclarées comme deux sites distincts.&lt;br /&gt;
&lt;br /&gt;
== 8. Vérifications après installation ==&lt;br /&gt;
&lt;br /&gt;
=== Vérifier la version installée ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /var/www/matomo&lt;br /&gt;
sudo -u www-data php console core:version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Vérifier les services ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl is-active apache2&lt;br /&gt;
systemctl is-active mariadb&lt;br /&gt;
systemctl is-active php8.4-fpm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Adapter la version PHP-FPM si nécessaire.&lt;br /&gt;
&lt;br /&gt;
=== Vérifier les points d&#039;accès ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
MATOMO_URL=&amp;quot;https://matomo.exemple.fr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl -I &amp;quot;$MATOMO_URL/matomo.js&amp;quot;&lt;br /&gt;
curl -I &amp;quot;$MATOMO_URL/matomo.php&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note :&#039;&#039;&#039; selon le comportement du serveur, une requête HEAD peut ne pas produire le même résultat qu&#039;une requête GET. Pour vérifier précisément les codes HTTP :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -sS -o /dev/null -w &amp;quot;HTTP %{http_code}\n&amp;quot; \&lt;br /&gt;
  &amp;quot;$MATOMO_URL/matomo.js&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;installation de Matomo ne garantit pas à elle seule que les applications transmettent leurs visites. Cette vérification relève des chapitres d&#039;intégration.&lt;br /&gt;
&lt;br /&gt;
== 9. Intégration aux applications ==&lt;br /&gt;
&lt;br /&gt;
=== Drupal ===&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Drupal]] pour :&lt;br /&gt;
&lt;br /&gt;
* L&#039;installation du module Drupal Matomo&lt;br /&gt;
* La configuration de l&#039;identifiant du site&lt;br /&gt;
* L&#039;adresse HTTPS du serveur Matomo&lt;br /&gt;
* Les exclusions des pages d&#039;administration&lt;br /&gt;
* Les vérifications de collecte&lt;br /&gt;
&lt;br /&gt;
=== Pleade ===&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Pleade]].&lt;br /&gt;
&lt;br /&gt;
=== Suivi IIIF et événements ===&lt;br /&gt;
&lt;br /&gt;
* [[Matomo/IIIF]]&lt;br /&gt;
* [[Matomo/Evenements]]&lt;br /&gt;
&lt;br /&gt;
== 10. Sécurité et maintenance ==&lt;br /&gt;
&lt;br /&gt;
Après installation, vérifier :&lt;br /&gt;
&lt;br /&gt;
* Que l&#039;interface d&#039;administration Matomo n&#039;est accessible qu&#039;aux utilisateurs ou réseaux autorisés&lt;br /&gt;
* Que les points de collecte nécessaires restent accessibles aux visiteurs&lt;br /&gt;
* Que le certificat HTTPS est valide&lt;br /&gt;
* Que les sauvegardes couvrent la base MariaDB et la configuration Matomo&lt;br /&gt;
* Que les mises à jour de sécurité sont suivies&lt;br /&gt;
&lt;br /&gt;
Voir :&lt;br /&gt;
&lt;br /&gt;
* [[Matomo/HAProxy]]&lt;br /&gt;
* [[Matomo/Maintenance]]&lt;br /&gt;
* [[Matomo/Debug]]&lt;br /&gt;
&lt;br /&gt;
== 11. Installations de référence ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Projet&lt;br /&gt;
! Serveur&lt;br /&gt;
! Domaine Matomo&lt;br /&gt;
! Particularités&lt;br /&gt;
|-&lt;br /&gt;
| AD64&lt;br /&gt;
| ad64&lt;br /&gt;
| ad64-matomo.pleade.com&lt;br /&gt;
| Matomo 5.10.1 ; deux Drupal suivis séparément&lt;br /&gt;
|-&lt;br /&gt;
| APBP2&lt;br /&gt;
| À compléter&lt;br /&gt;
| apbp2-matomo.pleade.com&lt;br /&gt;
| Publication via HAProxy avec restriction de l&#039;administration&lt;br /&gt;
|-&lt;br /&gt;
| MERCURE3&lt;br /&gt;
| À compléter&lt;br /&gt;
| mercure3-matomo.pleade.com&lt;br /&gt;
| Accès restreint à AJLSM&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les paramètres propres à chaque client (domaines, adresses IP, identifiants Matomo, backends HAProxy) ne doivent pas être intégrés directement dans les commandes génériques.&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=Matomo/Installation&amp;diff=6517</id>
		<title>Matomo/Installation</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=Matomo/Installation&amp;diff=6517"/>
		<updated>2026-10-20T10:55:15Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : /* 3. Activation de PHP-FPM */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Installation de Matomo sur une VM Ubuntu =&lt;br /&gt;
&lt;br /&gt;
== Objectif ==&lt;br /&gt;
&lt;br /&gt;
Cette procédure décrit l&#039;installation de Matomo sur les VM AJLSM hébergeant les applications Pleade et Drupal.&lt;br /&gt;
&lt;br /&gt;
Elle est destinée à être réutilisée pour les nouveaux projets, indépendamment du client et du nom de domaine.&lt;br /&gt;
&lt;br /&gt;
La configuration Apache, l&#039;intégration Drupal et la publication sécurisée par HAProxy sont détaillées dans des chapitres distincts :&lt;br /&gt;
&lt;br /&gt;
* [[Matomo/Apache]]&lt;br /&gt;
* [[Matomo/Drupal]]&lt;br /&gt;
* [[Matomo/HAProxy]]&lt;br /&gt;
* [[Matomo/Maintenance]]&lt;br /&gt;
&lt;br /&gt;
== 1. Environnement technique ==&lt;br /&gt;
&lt;br /&gt;
Matomo fonctionne avec Apache 2.4, PHP et MariaDB/MySQL.&lt;br /&gt;
&lt;br /&gt;
Deux modes d&#039;exécution de PHP sont possibles :&lt;br /&gt;
&lt;br /&gt;
mod_php : PHP est exécuté directement par Apache.&lt;br /&gt;
&lt;br /&gt;
PHP-FPM : PHP est exécuté par un service indépendant auquel Apache transmet les requêtes PHP.&lt;br /&gt;
&lt;br /&gt;
Le choix dépend de la configuration de la VM. Il n&#039;est pas nécessaire d&#039;installer PHP-FPM lorsque Matomo fonctionne déjà avec mod_php.&lt;br /&gt;
&lt;br /&gt;
=== Versions PHP ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Ubuntu&lt;br /&gt;
! Version PHP de référence&lt;br /&gt;
&lt;br /&gt;
! Observations&lt;br /&gt;
&lt;br /&gt;
Ubuntu 18.04&lt;br /&gt;
&lt;br /&gt;
PHP 8.1&lt;br /&gt;
&lt;br /&gt;
Installation historique avec version PHP ajoutée séparément&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
Ubuntu 24.04&lt;br /&gt;
&lt;br /&gt;
PHP 8.3&lt;br /&gt;
&lt;br /&gt;
Version fournie par Ubuntu&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
Ubuntu 26.04&lt;br /&gt;
&lt;br /&gt;
PHP 8.4&lt;br /&gt;
&lt;br /&gt;
Version utilisée sur AD64 en octobre 2026&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Vérifier systématiquement la compatibilité entre PHP et la version de Matomo installée.&lt;br /&gt;
&lt;br /&gt;
=== Composants nécessaires ===&lt;br /&gt;
&lt;br /&gt;
* Apache 2.4&lt;br /&gt;
* PHP-FPM&lt;br /&gt;
* MariaDB ou MySQL&lt;br /&gt;
* Extensions PHP requises par Matomo&lt;br /&gt;
* Accès HTTPS, directement ou via HAProxy&lt;br /&gt;
* Accès réseau permettant le téléchargement et les mises à jour de Matomo&lt;br /&gt;
&lt;br /&gt;
== 2. Installation des dépendances PHP ==&lt;br /&gt;
&lt;br /&gt;
Adapter la version de PHP à celle installée sur la VM.&lt;br /&gt;
&lt;br /&gt;
=== Ubuntu 24.04 — PHP 8.3 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install \&lt;br /&gt;
  php8.3-mysql php8.3-gd php8.3-curl php8.3-xml \&lt;br /&gt;
  php8.3-mbstring php8.3-zip php8.3-intl&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ubuntu 26.04 — PHP 8.4 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install \&lt;br /&gt;
  php8.4-mysql php8.4-gd php8.4-curl php8.4-xml \&lt;br /&gt;
  php8.4-mbstring php8.4-zip php8.4-intl&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Vérification ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php -v&lt;br /&gt;
php -m | grep -Ei &#039;mysqli|pdo_mysql|gd|curl|mbstring|xml|zip|intl&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3. Configuration PHP avec Apache ==&lt;br /&gt;
&lt;br /&gt;
=== Identifier le mode PHP utilisé ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apache2ctl -M 2&amp;gt;/dev/null | grep -E &#039;php_module|proxy_fcgi_module|mpm_&#039;&lt;br /&gt;
&lt;br /&gt;
systemctl list-units --all &#039;php*-fpm.service&#039; --no-pager&lt;br /&gt;
&lt;br /&gt;
php -v&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; la présence du module proxy_fcgi_module ne signifie pas nécessairement que PHP-FPM est utilisé. Il faut également vérifier les VirtualHosts et les gestionnaires PHP configurés.&lt;br /&gt;
&lt;br /&gt;
=== Cas 1 : Apache avec mod_php ===&lt;br /&gt;
&lt;br /&gt;
Dans cette configuration, PHP est exécuté directement par Apache.&lt;br /&gt;
&lt;br /&gt;
Exemple observé sur AD64 :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
mpm_prefork_module (shared)&lt;br /&gt;
php_module (shared)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aucun service PHP-FPM n&#039;est nécessaire.&lt;br /&gt;
&lt;br /&gt;
Vérifier qu&#039;Apache fonctionne :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl is-active apache2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pour une nouvelle installation utilisant ce mode, installer le module Apache correspondant à la version PHP disponible, par exemple :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install libapache2-mod-php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ne pas modifier le mode d&#039;exécution PHP d&#039;une VM existante sans vérifier les autres applications hébergées.&lt;br /&gt;
&lt;br /&gt;
=== Cas 2 : Apache avec PHP-FPM ===&lt;br /&gt;
&lt;br /&gt;
PHP-FPM est une autre architecture possible, notamment lorsqu&#039;une VM utilise plusieurs pools PHP.&lt;br /&gt;
&lt;br /&gt;
Exemple avec PHP 8.4 :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install php8.4-fpm&lt;br /&gt;
&lt;br /&gt;
sudo a2enmod proxy_fcgi setenvif&lt;br /&gt;
sudo a2enconf php8.4-fpm&lt;br /&gt;
&lt;br /&gt;
sudo apache2ctl configtest&lt;br /&gt;
sudo systemctl reload apache2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier ensuite :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl is-active php8.4-fpm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; si plusieurs applications utilisent différentes versions de PHP, privilégier une configuration explicite par VirtualHost ou par pool plutôt que l&#039;activation systématique d&#039;une configuration globale.&lt;br /&gt;
&lt;br /&gt;
=== Retour d&#039;expérience AD64 — octobre 2026 ===&lt;br /&gt;
&lt;br /&gt;
L&#039;installation Matomo 5.10.1 sur AD64 utilise :&lt;br /&gt;
&lt;br /&gt;
Apache 2.4&lt;br /&gt;
&lt;br /&gt;
PHP 8.4&lt;br /&gt;
&lt;br /&gt;
mod_php&lt;br /&gt;
&lt;br /&gt;
mpm_prefork&lt;br /&gt;
&lt;br /&gt;
MariaDB&lt;br /&gt;
&lt;br /&gt;
Aucun service PHP-FPM n&#039;est actif.&lt;br /&gt;
&lt;br /&gt;
Cette configuration est fonctionnelle et ne nécessite aucune modification.&lt;br /&gt;
&lt;br /&gt;
== 4. Préparation de MariaDB ==&lt;br /&gt;
&lt;br /&gt;
Vérifier que MariaDB est installé et actif :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl status mariadb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Matomo nécessite :&lt;br /&gt;
&lt;br /&gt;
* Une base de données dédiée&lt;br /&gt;
* Un utilisateur SQL dédié&lt;br /&gt;
* Des droits limités à cette base&lt;br /&gt;
&lt;br /&gt;
Exemple générique à adapter :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
CREATE DATABASE matomo&lt;br /&gt;
  CHARACTER SET utf8mb4&lt;br /&gt;
  COLLATE utf8mb4_unicode_ci;&lt;br /&gt;
&lt;br /&gt;
CREATE USER &#039;matomo&#039;@&#039;localhost&#039;&lt;br /&gt;
  IDENTIFIED BY &#039;MOT_DE_PASSE_FORT_A_REMPLACER&#039;;&lt;br /&gt;
&lt;br /&gt;
GRANT ALL PRIVILEGES ON matomo.*&lt;br /&gt;
  TO &#039;matomo&#039;@&#039;localhost&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ne jamais conserver le mot de passe d&#039;exemple dans une installation réelle.&lt;br /&gt;
&lt;br /&gt;
== 5. Permissions et sécurisation des fichiers Matomo ==&lt;br /&gt;
&lt;br /&gt;
=== Principes ===&lt;br /&gt;
&lt;br /&gt;
L&#039;installation Matomo est située dans :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/var/www/matomo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sur les VM AJLSM, lorsque PHP-FPM s&#039;exécute sous l&#039;utilisateur `www-data`, les fichiers de Matomo appartiennent normalement à `www-data:www-data`.&lt;br /&gt;
&lt;br /&gt;
Les permissions de référence sont :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Élément&lt;br /&gt;
! Permissions&lt;br /&gt;
! Observations&lt;br /&gt;
|-&lt;br /&gt;
| Répertoires de l&#039;application&lt;br /&gt;
| 755&lt;br /&gt;
| Lecture et traversée autorisées ; écriture réservée au propriétaire&lt;br /&gt;
|-&lt;br /&gt;
| Fichiers de l&#039;application&lt;br /&gt;
| 644&lt;br /&gt;
| Lecture autorisée ; écriture réservée au propriétaire&lt;br /&gt;
|-&lt;br /&gt;
| config/config.ini.php&lt;br /&gt;
| 600&lt;br /&gt;
| Fichier sensible contenant notamment les paramètres de connexion à MariaDB&lt;br /&gt;
|-&lt;br /&gt;
| Répertoires temporaires et de configuration&lt;br /&gt;
| 755&lt;br /&gt;
| Accessibles en écriture au compte PHP-FPM lorsqu&#039;il en est propriétaire&lt;br /&gt;
|-&lt;br /&gt;
| .well-known/acme-challenge&lt;br /&gt;
| 755&lt;br /&gt;
| Peut appartenir à root:root ; ne pas modifier sans vérifier la configuration ACME&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; les permissions 755 et 644 ne rendent pas les fichiers accessibles en écriture à tous. Elles permettent uniquement au propriétaire de les modifier.&lt;br /&gt;
&lt;br /&gt;
=== Configuration initiale ===&lt;br /&gt;
&lt;br /&gt;
Pour une nouvelle installation dont l&#039;ensemble des fichiers applicatifs doit appartenir à `www-data` :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo chown -R www-data:www-data /var/www/matomo&lt;br /&gt;
&lt;br /&gt;
sudo find /var/www/matomo -type d -exec chmod 755 {} \;&lt;br /&gt;
sudo find /var/www/matomo -type f -exec chmod 644 {} \;&lt;br /&gt;
&lt;br /&gt;
sudo chmod 600 /var/www/matomo/config/config.ini.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; ces commandes concernent une installation initiale, avant la création éventuelle de répertoires spécifiques par d&#039;autres services. Ne pas les réexécuter aveuglément sur une installation existante.&lt;br /&gt;
&lt;br /&gt;
Vérifier préalablement le compte utilisé par PHP-FPM. Si celui-ci est différent de `www-data`, adapter les propriétaires et permissions.&lt;br /&gt;
&lt;br /&gt;
=== Vérification des permissions ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
stat -c &#039;%A %a %U:%G %n&#039; \&lt;br /&gt;
  /var/www/matomo \&lt;br /&gt;
  /var/www/matomo/config \&lt;br /&gt;
  /var/www/matomo/config/config.ini.php \&lt;br /&gt;
  /var/www/matomo/tmp \&lt;br /&gt;
  /var/www/matomo/plugins \&lt;br /&gt;
  /var/www/matomo/matomo.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier la répartition des propriétaires :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo find /var/www/matomo -xdev -printf &#039;%u:%g\n&#039; \&lt;br /&gt;
  | sort | uniq -c | sort -nr&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identifier les fichiers ou répertoires accessibles en écriture à tous :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo find /var/www/matomo -xdev -perm -0002 \&lt;br /&gt;
  -printf &#039;%m %u:%g %p\n&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette dernière commande ne doit normalement rien retourner.&lt;br /&gt;
&lt;br /&gt;
=== Vérification des répertoires accessibles en écriture ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for DIR in config tmp plugins; do&lt;br /&gt;
  if sudo -u www-data test -w &amp;quot;/var/www/matomo/$DIR&amp;quot;; then&lt;br /&gt;
    echo &amp;quot;$DIR : écriture OK&amp;quot;&lt;br /&gt;
  else&lt;br /&gt;
    echo &amp;quot;$DIR : écriture NON autorisée&amp;quot;&lt;br /&gt;
  fi&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Adapter `www-data` si Matomo utilise un autre compte PHP-FPM.&lt;br /&gt;
&lt;br /&gt;
=== Cas particulier des répertoires ACME ===&lt;br /&gt;
&lt;br /&gt;
Certains répertoires peuvent être créés et administrés par le mécanisme de validation des certificats Let&#039;s Encrypt :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/var/www/matomo/.well-known&lt;br /&gt;
/var/www/matomo/.well-known/acme-challenge&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ils peuvent légitimement appartenir à `root:root` avec des permissions `755`.&lt;br /&gt;
&lt;br /&gt;
Ne pas modifier systématiquement leur propriétaire : vérifier au préalable le mécanisme de validation ACME utilisé sur la VM.&lt;br /&gt;
&lt;br /&gt;
=== Vérification après modification ===&lt;br /&gt;
&lt;br /&gt;
Après toute modification des permissions :&lt;br /&gt;
&lt;br /&gt;
* Vérifier que l&#039;interface Matomo reste accessible.&lt;br /&gt;
* Vérifier que la connexion à MariaDB fonctionne.&lt;br /&gt;
* Vérifier qu&#039;aucune erreur de permission n&#039;apparaît dans les journaux Apache/PHP-FPM.&lt;br /&gt;
* Vérifier que les statistiques continuent à être collectées.&lt;br /&gt;
&lt;br /&gt;
=== Retour d&#039;expérience — AD64, octobre 2026 ===&lt;br /&gt;
&lt;br /&gt;
L&#039;audit de `/var/www/matomo` sur AD64 a donné les résultats suivants :&lt;br /&gt;
&lt;br /&gt;
* 13 315 éléments appartenant à `www-data:www-data`.&lt;br /&gt;
* 2 répertoires appartenant à `root:root` : `.well-known` et `.well-known/acme-challenge`.&lt;br /&gt;
* Répertoires `config`, `tmp` et `plugins` accessibles en écriture à `www-data`.&lt;br /&gt;
* Aucun fichier ou répertoire accessible en écriture à tous.&lt;br /&gt;
* Fichier `config/config.ini.php` initialement en `644` : passage recommandé en `600`.&lt;br /&gt;
* Interface Matomo vérifiée fonctionnelle.&lt;br /&gt;
&lt;br /&gt;
Aucune autre modification des propriétaires ou des permissions n&#039;était nécessaire.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Conclusion :&#039;&#039;&#039; pour les nouvelles installations, appliquer des permissions adaptées dès le départ et réserver l&#039;accès aux fichiers sensibles. Sur les installations existantes, effectuer un audit avant toute modification globale.&lt;br /&gt;
&lt;br /&gt;
== 6. Configuration Apache et HTTPS ==&lt;br /&gt;
&lt;br /&gt;
La configuration du VirtualHost Matomo est décrite dans :&lt;br /&gt;
&lt;br /&gt;
[[Matomo/Apache]]&lt;br /&gt;
&lt;br /&gt;
Deux architectures sont possibles :&lt;br /&gt;
&lt;br /&gt;
* Apache assure directement la terminaison HTTPS.&lt;br /&gt;
* HAProxy assure la terminaison HTTPS et transmet les requêtes à Apache.&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;infrastructure AJLSM utilisant HAProxy, le certificat public est généralement géré sur les répartiteurs de charge.&lt;br /&gt;
&lt;br /&gt;
La procédure de configuration des certificats et des ACL est décrite dans :&lt;br /&gt;
&lt;br /&gt;
[[Matomo/HAProxy]]&lt;br /&gt;
&lt;br /&gt;
Pour une installation utilisant directement Certbot sur Apache :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install certbot python3-certbot-apache&lt;br /&gt;
sudo certbot --apache&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette procédure Certbot ne doit pas être appliquée automatiquement à une VM dont le HTTPS public est déjà géré par HAProxy.&lt;br /&gt;
&lt;br /&gt;
== 7. Initialisation de Matomo ==&lt;br /&gt;
&lt;br /&gt;
Après configuration du VirtualHost, ouvrir dans un navigateur l&#039;URL HTTPS prévue pour Matomo.&lt;br /&gt;
&lt;br /&gt;
L&#039;assistant d&#039;installation permet notamment de :&lt;br /&gt;
&lt;br /&gt;
# Vérifier les prérequis système&lt;br /&gt;
# Configurer la connexion à MariaDB&lt;br /&gt;
# Initialiser les tables Matomo&lt;br /&gt;
# Créer le compte administrateur&lt;br /&gt;
# Déclarer le premier site suivi&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; chaque application suivie doit disposer de son propre identifiant de site Matomo lorsque l&#039;on souhaite séparer ses statistiques.&lt;br /&gt;
&lt;br /&gt;
Exemple : une application Internet et une salle de lecture Drupal peuvent être déclarées comme deux sites distincts.&lt;br /&gt;
&lt;br /&gt;
== 8. Vérifications après installation ==&lt;br /&gt;
&lt;br /&gt;
=== Vérifier la version installée ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /var/www/matomo&lt;br /&gt;
sudo -u www-data php console core:version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Vérifier les services ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl is-active apache2&lt;br /&gt;
systemctl is-active mariadb&lt;br /&gt;
systemctl is-active php8.4-fpm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Adapter la version PHP-FPM si nécessaire.&lt;br /&gt;
&lt;br /&gt;
=== Vérifier les points d&#039;accès ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
MATOMO_URL=&amp;quot;https://matomo.exemple.fr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl -I &amp;quot;$MATOMO_URL/matomo.js&amp;quot;&lt;br /&gt;
curl -I &amp;quot;$MATOMO_URL/matomo.php&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note :&#039;&#039;&#039; selon le comportement du serveur, une requête HEAD peut ne pas produire le même résultat qu&#039;une requête GET. Pour vérifier précisément les codes HTTP :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -sS -o /dev/null -w &amp;quot;HTTP %{http_code}\n&amp;quot; \&lt;br /&gt;
  &amp;quot;$MATOMO_URL/matomo.js&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;installation de Matomo ne garantit pas à elle seule que les applications transmettent leurs visites. Cette vérification relève des chapitres d&#039;intégration.&lt;br /&gt;
&lt;br /&gt;
== 9. Intégration aux applications ==&lt;br /&gt;
&lt;br /&gt;
=== Drupal ===&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Drupal]] pour :&lt;br /&gt;
&lt;br /&gt;
* L&#039;installation du module Drupal Matomo&lt;br /&gt;
* La configuration de l&#039;identifiant du site&lt;br /&gt;
* L&#039;adresse HTTPS du serveur Matomo&lt;br /&gt;
* Les exclusions des pages d&#039;administration&lt;br /&gt;
* Les vérifications de collecte&lt;br /&gt;
&lt;br /&gt;
=== Pleade ===&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Pleade]].&lt;br /&gt;
&lt;br /&gt;
=== Suivi IIIF et événements ===&lt;br /&gt;
&lt;br /&gt;
* [[Matomo/IIIF]]&lt;br /&gt;
* [[Matomo/Evenements]]&lt;br /&gt;
&lt;br /&gt;
== 10. Sécurité et maintenance ==&lt;br /&gt;
&lt;br /&gt;
Après installation, vérifier :&lt;br /&gt;
&lt;br /&gt;
* Que l&#039;interface d&#039;administration Matomo n&#039;est accessible qu&#039;aux utilisateurs ou réseaux autorisés&lt;br /&gt;
* Que les points de collecte nécessaires restent accessibles aux visiteurs&lt;br /&gt;
* Que le certificat HTTPS est valide&lt;br /&gt;
* Que les sauvegardes couvrent la base MariaDB et la configuration Matomo&lt;br /&gt;
* Que les mises à jour de sécurité sont suivies&lt;br /&gt;
&lt;br /&gt;
Voir :&lt;br /&gt;
&lt;br /&gt;
* [[Matomo/HAProxy]]&lt;br /&gt;
* [[Matomo/Maintenance]]&lt;br /&gt;
* [[Matomo/Debug]]&lt;br /&gt;
&lt;br /&gt;
== 11. Installations de référence ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Projet&lt;br /&gt;
! Serveur&lt;br /&gt;
! Domaine Matomo&lt;br /&gt;
! Particularités&lt;br /&gt;
|-&lt;br /&gt;
| AD64&lt;br /&gt;
| ad64&lt;br /&gt;
| ad64-matomo.pleade.com&lt;br /&gt;
| Matomo 5.10.1 ; deux Drupal suivis séparément&lt;br /&gt;
|-&lt;br /&gt;
| APBP2&lt;br /&gt;
| À compléter&lt;br /&gt;
| apbp2-matomo.pleade.com&lt;br /&gt;
| Publication via HAProxy avec restriction de l&#039;administration&lt;br /&gt;
|-&lt;br /&gt;
| MERCURE3&lt;br /&gt;
| À compléter&lt;br /&gt;
| mercure3-matomo.pleade.com&lt;br /&gt;
| Accès restreint à AJLSM&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les paramètres propres à chaque client (domaines, adresses IP, identifiants Matomo, backends HAProxy) ne doivent pas être intégrés directement dans les commandes génériques.&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=Matomo/Installation&amp;diff=6516</id>
		<title>Matomo/Installation</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=Matomo/Installation&amp;diff=6516"/>
		<updated>2026-10-20T10:53:20Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : /* 1. Environnement technique */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Installation de Matomo sur une VM Ubuntu =&lt;br /&gt;
&lt;br /&gt;
== Objectif ==&lt;br /&gt;
&lt;br /&gt;
Cette procédure décrit l&#039;installation de Matomo sur les VM AJLSM hébergeant les applications Pleade et Drupal.&lt;br /&gt;
&lt;br /&gt;
Elle est destinée à être réutilisée pour les nouveaux projets, indépendamment du client et du nom de domaine.&lt;br /&gt;
&lt;br /&gt;
La configuration Apache, l&#039;intégration Drupal et la publication sécurisée par HAProxy sont détaillées dans des chapitres distincts :&lt;br /&gt;
&lt;br /&gt;
* [[Matomo/Apache]]&lt;br /&gt;
* [[Matomo/Drupal]]&lt;br /&gt;
* [[Matomo/HAProxy]]&lt;br /&gt;
* [[Matomo/Maintenance]]&lt;br /&gt;
&lt;br /&gt;
== 1. Environnement technique ==&lt;br /&gt;
&lt;br /&gt;
Matomo fonctionne avec Apache 2.4, PHP et MariaDB/MySQL.&lt;br /&gt;
&lt;br /&gt;
Deux modes d&#039;exécution de PHP sont possibles :&lt;br /&gt;
&lt;br /&gt;
mod_php : PHP est exécuté directement par Apache.&lt;br /&gt;
&lt;br /&gt;
PHP-FPM : PHP est exécuté par un service indépendant auquel Apache transmet les requêtes PHP.&lt;br /&gt;
&lt;br /&gt;
Le choix dépend de la configuration de la VM. Il n&#039;est pas nécessaire d&#039;installer PHP-FPM lorsque Matomo fonctionne déjà avec mod_php.&lt;br /&gt;
&lt;br /&gt;
=== Versions PHP ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Ubuntu&lt;br /&gt;
! Version PHP de référence&lt;br /&gt;
&lt;br /&gt;
! Observations&lt;br /&gt;
&lt;br /&gt;
Ubuntu 18.04&lt;br /&gt;
&lt;br /&gt;
PHP 8.1&lt;br /&gt;
&lt;br /&gt;
Installation historique avec version PHP ajoutée séparément&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
Ubuntu 24.04&lt;br /&gt;
&lt;br /&gt;
PHP 8.3&lt;br /&gt;
&lt;br /&gt;
Version fournie par Ubuntu&lt;br /&gt;
&lt;br /&gt;
-&lt;br /&gt;
&lt;br /&gt;
Ubuntu 26.04&lt;br /&gt;
&lt;br /&gt;
PHP 8.4&lt;br /&gt;
&lt;br /&gt;
Version utilisée sur AD64 en octobre 2026&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Vérifier systématiquement la compatibilité entre PHP et la version de Matomo installée.&lt;br /&gt;
&lt;br /&gt;
=== Composants nécessaires ===&lt;br /&gt;
&lt;br /&gt;
* Apache 2.4&lt;br /&gt;
* PHP-FPM&lt;br /&gt;
* MariaDB ou MySQL&lt;br /&gt;
* Extensions PHP requises par Matomo&lt;br /&gt;
* Accès HTTPS, directement ou via HAProxy&lt;br /&gt;
* Accès réseau permettant le téléchargement et les mises à jour de Matomo&lt;br /&gt;
&lt;br /&gt;
== 2. Installation des dépendances PHP ==&lt;br /&gt;
&lt;br /&gt;
Adapter la version de PHP à celle installée sur la VM.&lt;br /&gt;
&lt;br /&gt;
=== Ubuntu 24.04 — PHP 8.3 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install \&lt;br /&gt;
  php8.3-mysql php8.3-gd php8.3-curl php8.3-xml \&lt;br /&gt;
  php8.3-mbstring php8.3-zip php8.3-intl&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ubuntu 26.04 — PHP 8.4 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install \&lt;br /&gt;
  php8.4-mysql php8.4-gd php8.4-curl php8.4-xml \&lt;br /&gt;
  php8.4-mbstring php8.4-zip php8.4-intl&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Vérification ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php -v&lt;br /&gt;
php -m | grep -Ei &#039;mysqli|pdo_mysql|gd|curl|mbstring|xml|zip|intl&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3. Activation de PHP-FPM ==&lt;br /&gt;
&lt;br /&gt;
Exemple pour PHP 8.4 :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install php8.4-fpm&lt;br /&gt;
sudo a2enmod proxy_fcgi setenvif&lt;br /&gt;
sudo a2enconf php8.4-fpm&lt;br /&gt;
sudo systemctl reload apache2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier le service :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl status php8.4-fpm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; sur une VM hébergeant plusieurs applications PHP, vérifier les configurations Apache existantes avant d&#039;activer une configuration PHP-FPM globale.&lt;br /&gt;
&lt;br /&gt;
== 4. Préparation de MariaDB ==&lt;br /&gt;
&lt;br /&gt;
Vérifier que MariaDB est installé et actif :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl status mariadb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Matomo nécessite :&lt;br /&gt;
&lt;br /&gt;
* Une base de données dédiée&lt;br /&gt;
* Un utilisateur SQL dédié&lt;br /&gt;
* Des droits limités à cette base&lt;br /&gt;
&lt;br /&gt;
Exemple générique à adapter :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
CREATE DATABASE matomo&lt;br /&gt;
  CHARACTER SET utf8mb4&lt;br /&gt;
  COLLATE utf8mb4_unicode_ci;&lt;br /&gt;
&lt;br /&gt;
CREATE USER &#039;matomo&#039;@&#039;localhost&#039;&lt;br /&gt;
  IDENTIFIED BY &#039;MOT_DE_PASSE_FORT_A_REMPLACER&#039;;&lt;br /&gt;
&lt;br /&gt;
GRANT ALL PRIVILEGES ON matomo.*&lt;br /&gt;
  TO &#039;matomo&#039;@&#039;localhost&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ne jamais conserver le mot de passe d&#039;exemple dans une installation réelle.&lt;br /&gt;
&lt;br /&gt;
== 5. Permissions et sécurisation des fichiers Matomo ==&lt;br /&gt;
&lt;br /&gt;
=== Principes ===&lt;br /&gt;
&lt;br /&gt;
L&#039;installation Matomo est située dans :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/var/www/matomo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sur les VM AJLSM, lorsque PHP-FPM s&#039;exécute sous l&#039;utilisateur `www-data`, les fichiers de Matomo appartiennent normalement à `www-data:www-data`.&lt;br /&gt;
&lt;br /&gt;
Les permissions de référence sont :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Élément&lt;br /&gt;
! Permissions&lt;br /&gt;
! Observations&lt;br /&gt;
|-&lt;br /&gt;
| Répertoires de l&#039;application&lt;br /&gt;
| 755&lt;br /&gt;
| Lecture et traversée autorisées ; écriture réservée au propriétaire&lt;br /&gt;
|-&lt;br /&gt;
| Fichiers de l&#039;application&lt;br /&gt;
| 644&lt;br /&gt;
| Lecture autorisée ; écriture réservée au propriétaire&lt;br /&gt;
|-&lt;br /&gt;
| config/config.ini.php&lt;br /&gt;
| 600&lt;br /&gt;
| Fichier sensible contenant notamment les paramètres de connexion à MariaDB&lt;br /&gt;
|-&lt;br /&gt;
| Répertoires temporaires et de configuration&lt;br /&gt;
| 755&lt;br /&gt;
| Accessibles en écriture au compte PHP-FPM lorsqu&#039;il en est propriétaire&lt;br /&gt;
|-&lt;br /&gt;
| .well-known/acme-challenge&lt;br /&gt;
| 755&lt;br /&gt;
| Peut appartenir à root:root ; ne pas modifier sans vérifier la configuration ACME&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; les permissions 755 et 644 ne rendent pas les fichiers accessibles en écriture à tous. Elles permettent uniquement au propriétaire de les modifier.&lt;br /&gt;
&lt;br /&gt;
=== Configuration initiale ===&lt;br /&gt;
&lt;br /&gt;
Pour une nouvelle installation dont l&#039;ensemble des fichiers applicatifs doit appartenir à `www-data` :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo chown -R www-data:www-data /var/www/matomo&lt;br /&gt;
&lt;br /&gt;
sudo find /var/www/matomo -type d -exec chmod 755 {} \;&lt;br /&gt;
sudo find /var/www/matomo -type f -exec chmod 644 {} \;&lt;br /&gt;
&lt;br /&gt;
sudo chmod 600 /var/www/matomo/config/config.ini.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; ces commandes concernent une installation initiale, avant la création éventuelle de répertoires spécifiques par d&#039;autres services. Ne pas les réexécuter aveuglément sur une installation existante.&lt;br /&gt;
&lt;br /&gt;
Vérifier préalablement le compte utilisé par PHP-FPM. Si celui-ci est différent de `www-data`, adapter les propriétaires et permissions.&lt;br /&gt;
&lt;br /&gt;
=== Vérification des permissions ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
stat -c &#039;%A %a %U:%G %n&#039; \&lt;br /&gt;
  /var/www/matomo \&lt;br /&gt;
  /var/www/matomo/config \&lt;br /&gt;
  /var/www/matomo/config/config.ini.php \&lt;br /&gt;
  /var/www/matomo/tmp \&lt;br /&gt;
  /var/www/matomo/plugins \&lt;br /&gt;
  /var/www/matomo/matomo.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier la répartition des propriétaires :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo find /var/www/matomo -xdev -printf &#039;%u:%g\n&#039; \&lt;br /&gt;
  | sort | uniq -c | sort -nr&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identifier les fichiers ou répertoires accessibles en écriture à tous :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo find /var/www/matomo -xdev -perm -0002 \&lt;br /&gt;
  -printf &#039;%m %u:%g %p\n&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette dernière commande ne doit normalement rien retourner.&lt;br /&gt;
&lt;br /&gt;
=== Vérification des répertoires accessibles en écriture ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for DIR in config tmp plugins; do&lt;br /&gt;
  if sudo -u www-data test -w &amp;quot;/var/www/matomo/$DIR&amp;quot;; then&lt;br /&gt;
    echo &amp;quot;$DIR : écriture OK&amp;quot;&lt;br /&gt;
  else&lt;br /&gt;
    echo &amp;quot;$DIR : écriture NON autorisée&amp;quot;&lt;br /&gt;
  fi&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Adapter `www-data` si Matomo utilise un autre compte PHP-FPM.&lt;br /&gt;
&lt;br /&gt;
=== Cas particulier des répertoires ACME ===&lt;br /&gt;
&lt;br /&gt;
Certains répertoires peuvent être créés et administrés par le mécanisme de validation des certificats Let&#039;s Encrypt :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/var/www/matomo/.well-known&lt;br /&gt;
/var/www/matomo/.well-known/acme-challenge&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ils peuvent légitimement appartenir à `root:root` avec des permissions `755`.&lt;br /&gt;
&lt;br /&gt;
Ne pas modifier systématiquement leur propriétaire : vérifier au préalable le mécanisme de validation ACME utilisé sur la VM.&lt;br /&gt;
&lt;br /&gt;
=== Vérification après modification ===&lt;br /&gt;
&lt;br /&gt;
Après toute modification des permissions :&lt;br /&gt;
&lt;br /&gt;
* Vérifier que l&#039;interface Matomo reste accessible.&lt;br /&gt;
* Vérifier que la connexion à MariaDB fonctionne.&lt;br /&gt;
* Vérifier qu&#039;aucune erreur de permission n&#039;apparaît dans les journaux Apache/PHP-FPM.&lt;br /&gt;
* Vérifier que les statistiques continuent à être collectées.&lt;br /&gt;
&lt;br /&gt;
=== Retour d&#039;expérience — AD64, octobre 2026 ===&lt;br /&gt;
&lt;br /&gt;
L&#039;audit de `/var/www/matomo` sur AD64 a donné les résultats suivants :&lt;br /&gt;
&lt;br /&gt;
* 13 315 éléments appartenant à `www-data:www-data`.&lt;br /&gt;
* 2 répertoires appartenant à `root:root` : `.well-known` et `.well-known/acme-challenge`.&lt;br /&gt;
* Répertoires `config`, `tmp` et `plugins` accessibles en écriture à `www-data`.&lt;br /&gt;
* Aucun fichier ou répertoire accessible en écriture à tous.&lt;br /&gt;
* Fichier `config/config.ini.php` initialement en `644` : passage recommandé en `600`.&lt;br /&gt;
* Interface Matomo vérifiée fonctionnelle.&lt;br /&gt;
&lt;br /&gt;
Aucune autre modification des propriétaires ou des permissions n&#039;était nécessaire.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Conclusion :&#039;&#039;&#039; pour les nouvelles installations, appliquer des permissions adaptées dès le départ et réserver l&#039;accès aux fichiers sensibles. Sur les installations existantes, effectuer un audit avant toute modification globale.&lt;br /&gt;
&lt;br /&gt;
== 6. Configuration Apache et HTTPS ==&lt;br /&gt;
&lt;br /&gt;
La configuration du VirtualHost Matomo est décrite dans :&lt;br /&gt;
&lt;br /&gt;
[[Matomo/Apache]]&lt;br /&gt;
&lt;br /&gt;
Deux architectures sont possibles :&lt;br /&gt;
&lt;br /&gt;
* Apache assure directement la terminaison HTTPS.&lt;br /&gt;
* HAProxy assure la terminaison HTTPS et transmet les requêtes à Apache.&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;infrastructure AJLSM utilisant HAProxy, le certificat public est généralement géré sur les répartiteurs de charge.&lt;br /&gt;
&lt;br /&gt;
La procédure de configuration des certificats et des ACL est décrite dans :&lt;br /&gt;
&lt;br /&gt;
[[Matomo/HAProxy]]&lt;br /&gt;
&lt;br /&gt;
Pour une installation utilisant directement Certbot sur Apache :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install certbot python3-certbot-apache&lt;br /&gt;
sudo certbot --apache&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette procédure Certbot ne doit pas être appliquée automatiquement à une VM dont le HTTPS public est déjà géré par HAProxy.&lt;br /&gt;
&lt;br /&gt;
== 7. Initialisation de Matomo ==&lt;br /&gt;
&lt;br /&gt;
Après configuration du VirtualHost, ouvrir dans un navigateur l&#039;URL HTTPS prévue pour Matomo.&lt;br /&gt;
&lt;br /&gt;
L&#039;assistant d&#039;installation permet notamment de :&lt;br /&gt;
&lt;br /&gt;
# Vérifier les prérequis système&lt;br /&gt;
# Configurer la connexion à MariaDB&lt;br /&gt;
# Initialiser les tables Matomo&lt;br /&gt;
# Créer le compte administrateur&lt;br /&gt;
# Déclarer le premier site suivi&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; chaque application suivie doit disposer de son propre identifiant de site Matomo lorsque l&#039;on souhaite séparer ses statistiques.&lt;br /&gt;
&lt;br /&gt;
Exemple : une application Internet et une salle de lecture Drupal peuvent être déclarées comme deux sites distincts.&lt;br /&gt;
&lt;br /&gt;
== 8. Vérifications après installation ==&lt;br /&gt;
&lt;br /&gt;
=== Vérifier la version installée ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /var/www/matomo&lt;br /&gt;
sudo -u www-data php console core:version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Vérifier les services ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl is-active apache2&lt;br /&gt;
systemctl is-active mariadb&lt;br /&gt;
systemctl is-active php8.4-fpm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Adapter la version PHP-FPM si nécessaire.&lt;br /&gt;
&lt;br /&gt;
=== Vérifier les points d&#039;accès ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
MATOMO_URL=&amp;quot;https://matomo.exemple.fr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl -I &amp;quot;$MATOMO_URL/matomo.js&amp;quot;&lt;br /&gt;
curl -I &amp;quot;$MATOMO_URL/matomo.php&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note :&#039;&#039;&#039; selon le comportement du serveur, une requête HEAD peut ne pas produire le même résultat qu&#039;une requête GET. Pour vérifier précisément les codes HTTP :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -sS -o /dev/null -w &amp;quot;HTTP %{http_code}\n&amp;quot; \&lt;br /&gt;
  &amp;quot;$MATOMO_URL/matomo.js&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;installation de Matomo ne garantit pas à elle seule que les applications transmettent leurs visites. Cette vérification relève des chapitres d&#039;intégration.&lt;br /&gt;
&lt;br /&gt;
== 9. Intégration aux applications ==&lt;br /&gt;
&lt;br /&gt;
=== Drupal ===&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Drupal]] pour :&lt;br /&gt;
&lt;br /&gt;
* L&#039;installation du module Drupal Matomo&lt;br /&gt;
* La configuration de l&#039;identifiant du site&lt;br /&gt;
* L&#039;adresse HTTPS du serveur Matomo&lt;br /&gt;
* Les exclusions des pages d&#039;administration&lt;br /&gt;
* Les vérifications de collecte&lt;br /&gt;
&lt;br /&gt;
=== Pleade ===&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Pleade]].&lt;br /&gt;
&lt;br /&gt;
=== Suivi IIIF et événements ===&lt;br /&gt;
&lt;br /&gt;
* [[Matomo/IIIF]]&lt;br /&gt;
* [[Matomo/Evenements]]&lt;br /&gt;
&lt;br /&gt;
== 10. Sécurité et maintenance ==&lt;br /&gt;
&lt;br /&gt;
Après installation, vérifier :&lt;br /&gt;
&lt;br /&gt;
* Que l&#039;interface d&#039;administration Matomo n&#039;est accessible qu&#039;aux utilisateurs ou réseaux autorisés&lt;br /&gt;
* Que les points de collecte nécessaires restent accessibles aux visiteurs&lt;br /&gt;
* Que le certificat HTTPS est valide&lt;br /&gt;
* Que les sauvegardes couvrent la base MariaDB et la configuration Matomo&lt;br /&gt;
* Que les mises à jour de sécurité sont suivies&lt;br /&gt;
&lt;br /&gt;
Voir :&lt;br /&gt;
&lt;br /&gt;
* [[Matomo/HAProxy]]&lt;br /&gt;
* [[Matomo/Maintenance]]&lt;br /&gt;
* [[Matomo/Debug]]&lt;br /&gt;
&lt;br /&gt;
== 11. Installations de référence ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Projet&lt;br /&gt;
! Serveur&lt;br /&gt;
! Domaine Matomo&lt;br /&gt;
! Particularités&lt;br /&gt;
|-&lt;br /&gt;
| AD64&lt;br /&gt;
| ad64&lt;br /&gt;
| ad64-matomo.pleade.com&lt;br /&gt;
| Matomo 5.10.1 ; deux Drupal suivis séparément&lt;br /&gt;
|-&lt;br /&gt;
| APBP2&lt;br /&gt;
| À compléter&lt;br /&gt;
| apbp2-matomo.pleade.com&lt;br /&gt;
| Publication via HAProxy avec restriction de l&#039;administration&lt;br /&gt;
|-&lt;br /&gt;
| MERCURE3&lt;br /&gt;
| À compléter&lt;br /&gt;
| mercure3-matomo.pleade.com&lt;br /&gt;
| Accès restreint à AJLSM&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les paramètres propres à chaque client (domaines, adresses IP, identifiants Matomo, backends HAProxy) ne doivent pas être intégrés directement dans les commandes génériques.&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=Matomo/HAProxy&amp;diff=6515</id>
		<title>Matomo/HAProxy</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=Matomo/HAProxy&amp;diff=6515"/>
		<updated>2026-10-20T10:51:01Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : /* Exemple générique */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Publication et sécurisation de Matomo avec HAProxy =&lt;br /&gt;
&lt;br /&gt;
== Objectif ==&lt;br /&gt;
&lt;br /&gt;
Cette procédure décrit la publication d&#039;une instance Matomo derrière les répartiteurs HAProxy d&#039;AJLSM.&lt;br /&gt;
&lt;br /&gt;
Elle permet de :&lt;br /&gt;
&lt;br /&gt;
* Publier Matomo en HTTPS.&lt;br /&gt;
* Autoriser les requêtes de collecte des statistiques provenant des visiteurs.&lt;br /&gt;
* Réserver l&#039;interface d&#039;administration aux adresses IP autorisées.&lt;br /&gt;
* Déployer une configuration identique sur les deux HAProxy à l&#039;aide d&#039;Ansible.&lt;br /&gt;
* Vérifier le fonctionnement depuis une connexion extérieure.&lt;br /&gt;
&lt;br /&gt;
Cette procédure complète :&lt;br /&gt;
&lt;br /&gt;
* [[Matomo/Installation]]&lt;br /&gt;
* [[Matomo/Apache]]&lt;br /&gt;
* [[Matomo/Drupal]]&lt;br /&gt;
* [[Matomo/Debug]]&lt;br /&gt;
&lt;br /&gt;
== 1. Architecture ==&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;infrastructure AJLSM, le trafic suit généralement le chemin suivant :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Navigateur du visiteur&lt;br /&gt;
        |&lt;br /&gt;
        | HTTPS&lt;br /&gt;
        v&lt;br /&gt;
HAProxy (haproxy-01 / haproxy-02)&lt;br /&gt;
        |&lt;br /&gt;
        | HTTPS ou HTTP interne&lt;br /&gt;
        v&lt;br /&gt;
VM applicative&lt;br /&gt;
        |&lt;br /&gt;
        v&lt;br /&gt;
Apache + PHP-FPM + Matomo&lt;br /&gt;
        |&lt;br /&gt;
        v&lt;br /&gt;
MariaDB&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le navigateur charge le JavaScript Matomo et transmet les données de fréquentation au serveur Matomo.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; la collecte des statistiques doit fonctionner pour les visiteurs extérieurs, même lorsque l&#039;interface d&#039;administration Matomo est réservée à AJLSM.&lt;br /&gt;
&lt;br /&gt;
== 2. Prérequis ==&lt;br /&gt;
&lt;br /&gt;
Avant de modifier HAProxy, vérifier :&lt;br /&gt;
&lt;br /&gt;
* Que Matomo fonctionne sur la VM applicative.&lt;br /&gt;
* Que le VirtualHost Apache est configuré.&lt;br /&gt;
* Que le nom DNS public de Matomo est défini.&lt;br /&gt;
* Que le certificat HTTPS public est disponible sur HAProxy.&lt;br /&gt;
* Que le backend Matomo est joignable depuis les répartiteurs.&lt;br /&gt;
* Que l&#039;adresse IP ou le réseau autorisé pour l&#039;administration est connu.&lt;br /&gt;
&lt;br /&gt;
La configuration HAProxy est gérée par Ansible. Les modifications doivent être réalisées dans les fichiers sources du dépôt `ansible-ajlsm`, et non directement dans `/etc/haproxy/haproxy.cfg` sur les serveurs.&lt;br /&gt;
&lt;br /&gt;
== 3. Paramètres à personnaliser ==&lt;br /&gt;
&lt;br /&gt;
Pour chaque nouvelle installation, identifier les paramètres suivants :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Paramètre&lt;br /&gt;
! Exemple&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| Domaine Matomo&lt;br /&gt;
| matomo.exemple.fr&lt;br /&gt;
| Nom DNS public de Matomo&lt;br /&gt;
|-&lt;br /&gt;
| Backend&lt;br /&gt;
| back_ssl_projet_matomo&lt;br /&gt;
| Nom du backend HAProxy&lt;br /&gt;
|-&lt;br /&gt;
| Adresse de la VM&lt;br /&gt;
| 10.0.0.X&lt;br /&gt;
| Adresse privée de la VM hébergeant Matomo&lt;br /&gt;
|-&lt;br /&gt;
| Port backend&lt;br /&gt;
| 443&lt;br /&gt;
| Port HTTPS interne, si utilisé&lt;br /&gt;
|-&lt;br /&gt;
| ACL des administrateurs&lt;br /&gt;
| allowed_ajlsm&lt;br /&gt;
| Adresses IP autorisées à accéder à l&#039;interface&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 4. Configuration des ACL ==&lt;br /&gt;
&lt;br /&gt;
=== Principe ===&lt;br /&gt;
&lt;br /&gt;
Deux chemins sont nécessaires au suivi Matomo standard :&lt;br /&gt;
&lt;br /&gt;
* `/matomo.js` : chargement du JavaScript de suivi.&lt;br /&gt;
* `/matomo.php` : réception des données de fréquentation.&lt;br /&gt;
&lt;br /&gt;
Ces deux chemins doivent rester accessibles publiquement.&lt;br /&gt;
&lt;br /&gt;
Les autres chemins de l&#039;interface Matomo sont réservés aux adresses IP autorisées.&lt;br /&gt;
&lt;br /&gt;
=== Exemple générique ===&lt;br /&gt;
&lt;br /&gt;
Ajouter les règles suivantes dans le frontend HAProxy approprié :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
# MATOMO - PROJET&lt;br /&gt;
acl host_projet_matomo hdr(host),host_only -i matomo.exemple.fr&lt;br /&gt;
&lt;br /&gt;
# Ressources de collecte accessibles publiquement&lt;br /&gt;
acl projet_matomo_tracking path -i /matomo.js /matomo.php&lt;br /&gt;
&lt;br /&gt;
# Interface Matomo réservée à AJLSM&lt;br /&gt;
http-request deny if host_projet_matomo !allowed_ajlsm !projet_matomo_tracking&lt;br /&gt;
&lt;br /&gt;
# Redirection HTTP vers HTTPS&lt;br /&gt;
http-request redirect scheme https if host_projet_matomo !{ ssl_fc }&lt;br /&gt;
&lt;br /&gt;
# Routage vers le backend Matomo&lt;br /&gt;
use_backend back_ssl_projet_matomo if host_projet_matomo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; cet exemple utilise l&#039;ACL `allowed_ajlsm` déjà présente dans l&#039;infrastructure AJLSM. Vérifier son existence et son contenu avant de déployer la configuration.&lt;br /&gt;
&lt;br /&gt;
L&#039;ACL `path -i` effectue une correspondance exacte des chemins. Elle ne rend pas accessibles les autres pages de l&#039;administration Matomo.&lt;br /&gt;
&lt;br /&gt;
Cette configuration est adaptée au suivi JavaScript standard. Si des fonctionnalités supplémentaires nécessitent d&#039;autres points d&#039;accès, leurs chemins doivent être étudiés séparément avant toute ouverture.&lt;br /&gt;
&lt;br /&gt;
== 5. Configuration du backend ==&lt;br /&gt;
&lt;br /&gt;
=== Exemple HTTPS ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
backend back_ssl_projet_matomo&lt;br /&gt;
    server SSLPROJETMATOMO 10.0.0.X:443 check ssl verify none sni str(matomo.exemple.fr)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remplacer l&#039;adresse IP, le nom du serveur et le nom de domaine par les paramètres du projet.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Sécurité :&#039;&#039;&#039; `verify none` désactive la vérification du certificat présenté par le backend. Cette configuration existe sur AD64, mais ne doit pas être considérée comme une recommandation générale.&lt;br /&gt;
&lt;br /&gt;
Pour une nouvelle installation, privilégier une validation TLS du backend avec une autorité de certification appropriée lorsque l&#039;architecture le permet.&lt;br /&gt;
&lt;br /&gt;
=== Backend HTTP ===&lt;br /&gt;
&lt;br /&gt;
Un backend HTTP peut également être utilisé sur un réseau interne maîtrisé :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
backend back_projet_matomo&lt;br /&gt;
    server PROJETMATOMO 10.0.0.X:80 check&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le choix entre HTTP et HTTPS interne dépend de l&#039;architecture du projet et des exigences de sécurité.&lt;br /&gt;
&lt;br /&gt;
== 6. Certificats HTTPS ==&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;infrastructure AJLSM, les certificats publics HAProxy peuvent être gérés par `acme.sh`.&lt;br /&gt;
&lt;br /&gt;
Sur les serveurs HAProxy concernés, vérifier :&lt;br /&gt;
&lt;br /&gt;
* L&#039;existence du certificat pour le domaine Matomo.&lt;br /&gt;
* Sa date d&#039;expiration.&lt;br /&gt;
* La configuration de renouvellement automatique.&lt;br /&gt;
* Le mécanisme de déploiement du certificat dans HAProxy.&lt;br /&gt;
&lt;br /&gt;
Exemple de vérification depuis un poste client :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
openssl s_client \&lt;br /&gt;
  -connect matomo.exemple.fr:443 \&lt;br /&gt;
  -servername matomo.exemple.fr &amp;lt;/dev/null 2&amp;gt;/dev/null \&lt;br /&gt;
  | openssl x509 -noout -subject -issuer -dates&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La présence d&#039;une tâche automatique de renouvellement ne garantit pas à elle seule que le déploiement d&#039;un nouveau certificat fonctionnera. Le renouvellement et le rechargement effectif du certificat doivent être contrôlés.&lt;br /&gt;
&lt;br /&gt;
== 7. Déploiement avec Ansible ==&lt;br /&gt;
Voir aussi la configuration du WAF avec ansible : [[WAF_2026#Ansible|WAF 2026]]&lt;br /&gt;
=== Modification ===&lt;br /&gt;
&lt;br /&gt;
Depuis le Mac d&#039;administration :&lt;br /&gt;
&lt;br /&gt;
# Ouvrir le dépôt `ansible-ajlsm`.&lt;br /&gt;
# Modifier la configuration HAProxy dans les sources Ansible.&lt;br /&gt;
# Ajouter les ACL et le routage du nouveau domaine Matomo.&lt;br /&gt;
# Vérifier que les backends sont définis.&lt;br /&gt;
# Ne pas modifier directement les configurations générées sur les deux serveurs.&lt;br /&gt;
&lt;br /&gt;
=== Vérification de la syntaxe du playbook ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer --syntax-check&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Simulation du déploiement ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer --check --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier :&lt;br /&gt;
&lt;br /&gt;
* Que les modifications sont identiques sur les deux HAProxy.&lt;br /&gt;
* Que seuls les blocs attendus changent.&lt;br /&gt;
* Qu&#039;aucune configuration d&#039;un autre client n&#039;est modifiée.&lt;br /&gt;
* Qu&#039;aucune erreur n&#039;est signalée.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; le mode `--check` est une simulation. Il ne garantit pas à lui seul le succès du déploiement réel ni le comportement des ACL en production.&lt;br /&gt;
&lt;br /&gt;
=== Déploiement réel ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier le résultat du playbook sur les deux serveurs.&lt;br /&gt;
&lt;br /&gt;
Si le playbook prévoit un redémarrage ou un rechargement HAProxy, contrôler ensuite que les services restent actifs et que les applications existantes répondent normalement.&lt;br /&gt;
&lt;br /&gt;
== 8. Vérification depuis une connexion extérieure ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; effectuer les tests depuis une connexion qui n&#039;utilise ni l&#039;adresse IP publique du bureau ni le VPN AJLSM.&lt;br /&gt;
&lt;br /&gt;
Une connexion autorisée ne permet pas de vérifier correctement le refus d&#039;accès à l&#039;administration.&lt;br /&gt;
&lt;br /&gt;
=== Tester les ressources de suivi ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
MATOMO_URL=&amp;quot;https://matomo.exemple.fr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
for RESOURCE in matomo.js matomo.php; do&lt;br /&gt;
    echo &amp;quot;===== /$RESOURCE =====&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    curl -sS -o /dev/null -w &amp;quot;HTTP %{http_code}\n&amp;quot; \&lt;br /&gt;
        &amp;quot;$MATOMO_URL/$RESOURCE&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultats attendus pour l&#039;installation standard :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Ressource&lt;br /&gt;
! Résultat attendu&lt;br /&gt;
|-&lt;br /&gt;
| /matomo.js&lt;br /&gt;
| HTTP 200&lt;br /&gt;
|-&lt;br /&gt;
| /matomo.php&lt;br /&gt;
| Accessible sans HTTP 403 HAProxy&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Remarque :&#039;&#039;&#039; une réponse HTTP 200 de `matomo.php` sans paramètres de suivi ne constitue pas une preuve de collecte effective.&lt;br /&gt;
&lt;br /&gt;
=== Tester la protection de l&#039;administration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -sS -o /dev/null -w &amp;quot;HTTP %{http_code}\n&amp;quot; \&lt;br /&gt;
    &amp;quot;$MATOMO_URL/&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat attendu depuis une adresse IP extérieure non autorisée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
HTTP 403&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tester depuis une adresse autorisée ===&lt;br /&gt;
&lt;br /&gt;
Depuis le réseau AJLSM ou un accès VPN autorisé, vérifier que l&#039;interface Matomo reste accessible et que l&#039;authentification Matomo fonctionne.&lt;br /&gt;
&lt;br /&gt;
== 9. Vérification de la collecte ==&lt;br /&gt;
&lt;br /&gt;
Une fois les règles HAProxy appliquées :&lt;br /&gt;
&lt;br /&gt;
# Ouvrir une application Drupal ou Pleade suivie par Matomo.&lt;br /&gt;
# Naviguer sur plusieurs pages publiques.&lt;br /&gt;
# Vérifier l&#039;envoi des requêtes de suivi dans les outils réseau du navigateur.&lt;br /&gt;
# Vérifier l&#039;apparition des visites dans l&#039;interface Matomo.&lt;br /&gt;
&lt;br /&gt;
Pour une vérification directe en base :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT&lt;br /&gt;
    idsite,&lt;br /&gt;
    COUNT(*) AS visites,&lt;br /&gt;
    MAX(visit_last_action_time) AS derniere_activite&lt;br /&gt;
FROM matomo_log_visit&lt;br /&gt;
GROUP BY idsite;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette requête doit être exécutée dans la base Matomo avec un compte disposant des droits nécessaires.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Drupal]] et [[Matomo/Debug]].&lt;br /&gt;
&lt;br /&gt;
== 10. Exemple validé : AD64 — octobre 2026 ==&lt;br /&gt;
&lt;br /&gt;
=== Environnement ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Élément&lt;br /&gt;
! Valeur&lt;br /&gt;
|-&lt;br /&gt;
| Serveur Matomo&lt;br /&gt;
| ad64&lt;br /&gt;
|-&lt;br /&gt;
| Domaine&lt;br /&gt;
| ad64-matomo.pleade.com&lt;br /&gt;
|-&lt;br /&gt;
| Adresse privée de la VM&lt;br /&gt;
| 10.0.0.41&lt;br /&gt;
|-&lt;br /&gt;
| Backend HTTPS&lt;br /&gt;
| back_ssl_ad64_matomo&lt;br /&gt;
|-&lt;br /&gt;
| Répartiteurs&lt;br /&gt;
| haproxy-01 et haproxy-02&lt;br /&gt;
|-&lt;br /&gt;
| Applications suivies&lt;br /&gt;
| Drupal Internet et Drupal Salle de lecture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Configuration HAProxy ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
# AD64 MATOMO&lt;br /&gt;
acl host_ad64_matomo hdr(host),host_only -i ad64-matomo.pleade.com&lt;br /&gt;
&lt;br /&gt;
# Points de collecte accessibles publiquement&lt;br /&gt;
acl ad64_matomo_tracking path -i /matomo.js /matomo.php&lt;br /&gt;
&lt;br /&gt;
# Administration réservée à AJLSM&lt;br /&gt;
http-request deny if host_ad64_matomo !allowed_ajlsm !ad64_matomo_tracking&lt;br /&gt;
&lt;br /&gt;
http-request redirect scheme https if host_ad64_matomo !{ ssl_fc }&lt;br /&gt;
&lt;br /&gt;
use_backend back_ssl_ad64_matomo if host_ad64_matomo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Backend HTTPS existant :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
backend back_ssl_ad64_matomo&lt;br /&gt;
    server SSLAD64MATOMO 10.0.0.41:443 check ssl verify none sni str(ad64-matomo.pleade.com)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;ancien backend HTTP `back_ad64_matomo` a été conservé sans modification, bien qu&#039;il ne soit plus utilisé par ce routage.&lt;br /&gt;
&lt;br /&gt;
=== Résultats des tests ===&lt;br /&gt;
&lt;br /&gt;
Les vérifications réalisées le 20 octobre 2026 depuis une connexion extérieure au bureau ont donné :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Test&lt;br /&gt;
! Résultat&lt;br /&gt;
|-&lt;br /&gt;
| https://ad64-matomo.pleade.com/matomo.js&lt;br /&gt;
| HTTP 200&lt;br /&gt;
|-&lt;br /&gt;
| https://ad64-matomo.pleade.com/matomo.php&lt;br /&gt;
| HTTP 200&lt;br /&gt;
|-&lt;br /&gt;
| https://ad64-matomo.pleade.com/&lt;br /&gt;
| HTTP 403&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les visites Drupal Internet et Salle de lecture avaient également été enregistrées dans MariaDB, avec les identifiants Matomo 2 et 3.&lt;br /&gt;
&lt;br /&gt;
La collecte et la restriction d&#039;accès ont donc été vérifiées.&lt;br /&gt;
&lt;br /&gt;
== 11. Points de vigilance ==&lt;br /&gt;
&lt;br /&gt;
* Ne jamais ouvrir toute l&#039;interface Matomo à Internet uniquement pour permettre la collecte.&lt;br /&gt;
* Ne pas autoriser systématiquement les adresses IP du client à accéder à l&#039;administration.&lt;br /&gt;
* Ne pas bloquer les points de collecte nécessaires aux visiteurs.&lt;br /&gt;
* Ne pas modifier directement les fichiers HAProxy générés par Ansible.&lt;br /&gt;
* Tester depuis une véritable connexion extérieure.&lt;br /&gt;
* Vérifier le certificat HTTPS et son renouvellement.&lt;br /&gt;
* Vérifier que la collecte réelle fonctionne, au-delà du simple chargement du JavaScript.&lt;br /&gt;
&lt;br /&gt;
== 12. Maintenance et diagnostic ==&lt;br /&gt;
&lt;br /&gt;
En cas d&#039;anomalie, vérifier successivement :&lt;br /&gt;
&lt;br /&gt;
# La résolution DNS du domaine Matomo.&lt;br /&gt;
# Le certificat HTTPS présenté par HAProxy.&lt;br /&gt;
# La correspondance de l&#039;ACL `host`.&lt;br /&gt;
# Les règles `http-request deny`.&lt;br /&gt;
# Les chemins autorisés pour le suivi.&lt;br /&gt;
# L&#039;état du backend HAProxy.&lt;br /&gt;
# La disponibilité d&#039;Apache et PHP-FPM sur la VM.&lt;br /&gt;
# La réception effective des visites dans Matomo.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Debug]] et [[Matomo/Maintenance]].&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=Matomo/HAProxy&amp;diff=6514</id>
		<title>Matomo/HAProxy</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=Matomo/HAProxy&amp;diff=6514"/>
		<updated>2026-10-20T10:45:52Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : /* 7. Déploiement avec Ansible */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Publication et sécurisation de Matomo avec HAProxy =&lt;br /&gt;
&lt;br /&gt;
== Objectif ==&lt;br /&gt;
&lt;br /&gt;
Cette procédure décrit la publication d&#039;une instance Matomo derrière les répartiteurs HAProxy d&#039;AJLSM.&lt;br /&gt;
&lt;br /&gt;
Elle permet de :&lt;br /&gt;
&lt;br /&gt;
* Publier Matomo en HTTPS.&lt;br /&gt;
* Autoriser les requêtes de collecte des statistiques provenant des visiteurs.&lt;br /&gt;
* Réserver l&#039;interface d&#039;administration aux adresses IP autorisées.&lt;br /&gt;
* Déployer une configuration identique sur les deux HAProxy à l&#039;aide d&#039;Ansible.&lt;br /&gt;
* Vérifier le fonctionnement depuis une connexion extérieure.&lt;br /&gt;
&lt;br /&gt;
Cette procédure complète :&lt;br /&gt;
&lt;br /&gt;
* [[Matomo/Installation]]&lt;br /&gt;
* [[Matomo/Apache]]&lt;br /&gt;
* [[Matomo/Drupal]]&lt;br /&gt;
* [[Matomo/Debug]]&lt;br /&gt;
&lt;br /&gt;
== 1. Architecture ==&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;infrastructure AJLSM, le trafic suit généralement le chemin suivant :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Navigateur du visiteur&lt;br /&gt;
        |&lt;br /&gt;
        | HTTPS&lt;br /&gt;
        v&lt;br /&gt;
HAProxy (haproxy-01 / haproxy-02)&lt;br /&gt;
        |&lt;br /&gt;
        | HTTPS ou HTTP interne&lt;br /&gt;
        v&lt;br /&gt;
VM applicative&lt;br /&gt;
        |&lt;br /&gt;
        v&lt;br /&gt;
Apache + PHP-FPM + Matomo&lt;br /&gt;
        |&lt;br /&gt;
        v&lt;br /&gt;
MariaDB&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le navigateur charge le JavaScript Matomo et transmet les données de fréquentation au serveur Matomo.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; la collecte des statistiques doit fonctionner pour les visiteurs extérieurs, même lorsque l&#039;interface d&#039;administration Matomo est réservée à AJLSM.&lt;br /&gt;
&lt;br /&gt;
== 2. Prérequis ==&lt;br /&gt;
&lt;br /&gt;
Avant de modifier HAProxy, vérifier :&lt;br /&gt;
&lt;br /&gt;
* Que Matomo fonctionne sur la VM applicative.&lt;br /&gt;
* Que le VirtualHost Apache est configuré.&lt;br /&gt;
* Que le nom DNS public de Matomo est défini.&lt;br /&gt;
* Que le certificat HTTPS public est disponible sur HAProxy.&lt;br /&gt;
* Que le backend Matomo est joignable depuis les répartiteurs.&lt;br /&gt;
* Que l&#039;adresse IP ou le réseau autorisé pour l&#039;administration est connu.&lt;br /&gt;
&lt;br /&gt;
La configuration HAProxy est gérée par Ansible. Les modifications doivent être réalisées dans les fichiers sources du dépôt `ansible-ajlsm`, et non directement dans `/etc/haproxy/haproxy.cfg` sur les serveurs.&lt;br /&gt;
&lt;br /&gt;
== 3. Paramètres à personnaliser ==&lt;br /&gt;
&lt;br /&gt;
Pour chaque nouvelle installation, identifier les paramètres suivants :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Paramètre&lt;br /&gt;
! Exemple&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| Domaine Matomo&lt;br /&gt;
| matomo.exemple.fr&lt;br /&gt;
| Nom DNS public de Matomo&lt;br /&gt;
|-&lt;br /&gt;
| Backend&lt;br /&gt;
| back_ssl_projet_matomo&lt;br /&gt;
| Nom du backend HAProxy&lt;br /&gt;
|-&lt;br /&gt;
| Adresse de la VM&lt;br /&gt;
| 10.0.0.X&lt;br /&gt;
| Adresse privée de la VM hébergeant Matomo&lt;br /&gt;
|-&lt;br /&gt;
| Port backend&lt;br /&gt;
| 443&lt;br /&gt;
| Port HTTPS interne, si utilisé&lt;br /&gt;
|-&lt;br /&gt;
| ACL des administrateurs&lt;br /&gt;
| allowed_ajlsm&lt;br /&gt;
| Adresses IP autorisées à accéder à l&#039;interface&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 4. Configuration des ACL ==&lt;br /&gt;
&lt;br /&gt;
=== Principe ===&lt;br /&gt;
&lt;br /&gt;
Deux chemins sont nécessaires au suivi Matomo standard :&lt;br /&gt;
&lt;br /&gt;
* `/matomo.js` : chargement du JavaScript de suivi.&lt;br /&gt;
* `/matomo.php` : réception des données de fréquentation.&lt;br /&gt;
&lt;br /&gt;
Ces deux chemins doivent rester accessibles publiquement.&lt;br /&gt;
&lt;br /&gt;
Les autres chemins de l&#039;interface Matomo sont réservés aux adresses IP autorisées.&lt;br /&gt;
&lt;br /&gt;
=== Exemple générique ===&lt;br /&gt;
&lt;br /&gt;
Ajouter les règles suivantes dans le frontend HAProxy approprié :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;haproxy&amp;quot;&amp;gt;&lt;br /&gt;
# MATOMO - PROJET&lt;br /&gt;
acl host_projet_matomo hdr(host),host_only -i matomo.exemple.fr&lt;br /&gt;
&lt;br /&gt;
# Ressources de collecte accessibles publiquement&lt;br /&gt;
acl projet_matomo_tracking path -i /matomo.js /matomo.php&lt;br /&gt;
&lt;br /&gt;
# Interface Matomo réservée à AJLSM&lt;br /&gt;
http-request deny if host_projet_matomo !allowed_ajlsm !projet_matomo_tracking&lt;br /&gt;
&lt;br /&gt;
# Redirection HTTP vers HTTPS&lt;br /&gt;
http-request redirect scheme https if host_projet_matomo !{ ssl_fc }&lt;br /&gt;
&lt;br /&gt;
# Routage vers le backend Matomo&lt;br /&gt;
use_backend back_ssl_projet_matomo if host_projet_matomo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; cet exemple utilise l&#039;ACL `allowed_ajlsm` déjà présente dans l&#039;infrastructure AJLSM. Vérifier son existence et son contenu avant de déployer la configuration.&lt;br /&gt;
&lt;br /&gt;
L&#039;ACL `path -i` effectue une correspondance exacte des chemins. Elle ne rend pas accessibles les autres pages de l&#039;administration Matomo.&lt;br /&gt;
&lt;br /&gt;
Cette configuration est adaptée au suivi JavaScript standard. Si des fonctionnalités supplémentaires nécessitent d&#039;autres points d&#039;accès, leurs chemins doivent être étudiés séparément avant toute ouverture.&lt;br /&gt;
&lt;br /&gt;
== 5. Configuration du backend ==&lt;br /&gt;
&lt;br /&gt;
=== Exemple HTTPS ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
backend back_ssl_projet_matomo&lt;br /&gt;
    server SSLPROJETMATOMO 10.0.0.X:443 check ssl verify none sni str(matomo.exemple.fr)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remplacer l&#039;adresse IP, le nom du serveur et le nom de domaine par les paramètres du projet.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Sécurité :&#039;&#039;&#039; `verify none` désactive la vérification du certificat présenté par le backend. Cette configuration existe sur AD64, mais ne doit pas être considérée comme une recommandation générale.&lt;br /&gt;
&lt;br /&gt;
Pour une nouvelle installation, privilégier une validation TLS du backend avec une autorité de certification appropriée lorsque l&#039;architecture le permet.&lt;br /&gt;
&lt;br /&gt;
=== Backend HTTP ===&lt;br /&gt;
&lt;br /&gt;
Un backend HTTP peut également être utilisé sur un réseau interne maîtrisé :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
backend back_projet_matomo&lt;br /&gt;
    server PROJETMATOMO 10.0.0.X:80 check&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le choix entre HTTP et HTTPS interne dépend de l&#039;architecture du projet et des exigences de sécurité.&lt;br /&gt;
&lt;br /&gt;
== 6. Certificats HTTPS ==&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;infrastructure AJLSM, les certificats publics HAProxy peuvent être gérés par `acme.sh`.&lt;br /&gt;
&lt;br /&gt;
Sur les serveurs HAProxy concernés, vérifier :&lt;br /&gt;
&lt;br /&gt;
* L&#039;existence du certificat pour le domaine Matomo.&lt;br /&gt;
* Sa date d&#039;expiration.&lt;br /&gt;
* La configuration de renouvellement automatique.&lt;br /&gt;
* Le mécanisme de déploiement du certificat dans HAProxy.&lt;br /&gt;
&lt;br /&gt;
Exemple de vérification depuis un poste client :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
openssl s_client \&lt;br /&gt;
  -connect matomo.exemple.fr:443 \&lt;br /&gt;
  -servername matomo.exemple.fr &amp;lt;/dev/null 2&amp;gt;/dev/null \&lt;br /&gt;
  | openssl x509 -noout -subject -issuer -dates&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La présence d&#039;une tâche automatique de renouvellement ne garantit pas à elle seule que le déploiement d&#039;un nouveau certificat fonctionnera. Le renouvellement et le rechargement effectif du certificat doivent être contrôlés.&lt;br /&gt;
&lt;br /&gt;
== 7. Déploiement avec Ansible ==&lt;br /&gt;
Voir aussi la configuration du WAF avec ansible : [[WAF_2026#Ansible|WAF 2026]]&lt;br /&gt;
=== Modification ===&lt;br /&gt;
&lt;br /&gt;
Depuis le Mac d&#039;administration :&lt;br /&gt;
&lt;br /&gt;
# Ouvrir le dépôt `ansible-ajlsm`.&lt;br /&gt;
# Modifier la configuration HAProxy dans les sources Ansible.&lt;br /&gt;
# Ajouter les ACL et le routage du nouveau domaine Matomo.&lt;br /&gt;
# Vérifier que les backends sont définis.&lt;br /&gt;
# Ne pas modifier directement les configurations générées sur les deux serveurs.&lt;br /&gt;
&lt;br /&gt;
=== Vérification de la syntaxe du playbook ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer --syntax-check&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Simulation du déploiement ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer --check --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier :&lt;br /&gt;
&lt;br /&gt;
* Que les modifications sont identiques sur les deux HAProxy.&lt;br /&gt;
* Que seuls les blocs attendus changent.&lt;br /&gt;
* Qu&#039;aucune configuration d&#039;un autre client n&#039;est modifiée.&lt;br /&gt;
* Qu&#039;aucune erreur n&#039;est signalée.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; le mode `--check` est une simulation. Il ne garantit pas à lui seul le succès du déploiement réel ni le comportement des ACL en production.&lt;br /&gt;
&lt;br /&gt;
=== Déploiement réel ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier le résultat du playbook sur les deux serveurs.&lt;br /&gt;
&lt;br /&gt;
Si le playbook prévoit un redémarrage ou un rechargement HAProxy, contrôler ensuite que les services restent actifs et que les applications existantes répondent normalement.&lt;br /&gt;
&lt;br /&gt;
== 8. Vérification depuis une connexion extérieure ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; effectuer les tests depuis une connexion qui n&#039;utilise ni l&#039;adresse IP publique du bureau ni le VPN AJLSM.&lt;br /&gt;
&lt;br /&gt;
Une connexion autorisée ne permet pas de vérifier correctement le refus d&#039;accès à l&#039;administration.&lt;br /&gt;
&lt;br /&gt;
=== Tester les ressources de suivi ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
MATOMO_URL=&amp;quot;https://matomo.exemple.fr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
for RESOURCE in matomo.js matomo.php; do&lt;br /&gt;
    echo &amp;quot;===== /$RESOURCE =====&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    curl -sS -o /dev/null -w &amp;quot;HTTP %{http_code}\n&amp;quot; \&lt;br /&gt;
        &amp;quot;$MATOMO_URL/$RESOURCE&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultats attendus pour l&#039;installation standard :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Ressource&lt;br /&gt;
! Résultat attendu&lt;br /&gt;
|-&lt;br /&gt;
| /matomo.js&lt;br /&gt;
| HTTP 200&lt;br /&gt;
|-&lt;br /&gt;
| /matomo.php&lt;br /&gt;
| Accessible sans HTTP 403 HAProxy&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Remarque :&#039;&#039;&#039; une réponse HTTP 200 de `matomo.php` sans paramètres de suivi ne constitue pas une preuve de collecte effective.&lt;br /&gt;
&lt;br /&gt;
=== Tester la protection de l&#039;administration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -sS -o /dev/null -w &amp;quot;HTTP %{http_code}\n&amp;quot; \&lt;br /&gt;
    &amp;quot;$MATOMO_URL/&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat attendu depuis une adresse IP extérieure non autorisée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
HTTP 403&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tester depuis une adresse autorisée ===&lt;br /&gt;
&lt;br /&gt;
Depuis le réseau AJLSM ou un accès VPN autorisé, vérifier que l&#039;interface Matomo reste accessible et que l&#039;authentification Matomo fonctionne.&lt;br /&gt;
&lt;br /&gt;
== 9. Vérification de la collecte ==&lt;br /&gt;
&lt;br /&gt;
Une fois les règles HAProxy appliquées :&lt;br /&gt;
&lt;br /&gt;
# Ouvrir une application Drupal ou Pleade suivie par Matomo.&lt;br /&gt;
# Naviguer sur plusieurs pages publiques.&lt;br /&gt;
# Vérifier l&#039;envoi des requêtes de suivi dans les outils réseau du navigateur.&lt;br /&gt;
# Vérifier l&#039;apparition des visites dans l&#039;interface Matomo.&lt;br /&gt;
&lt;br /&gt;
Pour une vérification directe en base :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT&lt;br /&gt;
    idsite,&lt;br /&gt;
    COUNT(*) AS visites,&lt;br /&gt;
    MAX(visit_last_action_time) AS derniere_activite&lt;br /&gt;
FROM matomo_log_visit&lt;br /&gt;
GROUP BY idsite;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette requête doit être exécutée dans la base Matomo avec un compte disposant des droits nécessaires.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Drupal]] et [[Matomo/Debug]].&lt;br /&gt;
&lt;br /&gt;
== 10. Exemple validé : AD64 — octobre 2026 ==&lt;br /&gt;
&lt;br /&gt;
=== Environnement ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Élément&lt;br /&gt;
! Valeur&lt;br /&gt;
|-&lt;br /&gt;
| Serveur Matomo&lt;br /&gt;
| ad64&lt;br /&gt;
|-&lt;br /&gt;
| Domaine&lt;br /&gt;
| ad64-matomo.pleade.com&lt;br /&gt;
|-&lt;br /&gt;
| Adresse privée de la VM&lt;br /&gt;
| 10.0.0.41&lt;br /&gt;
|-&lt;br /&gt;
| Backend HTTPS&lt;br /&gt;
| back_ssl_ad64_matomo&lt;br /&gt;
|-&lt;br /&gt;
| Répartiteurs&lt;br /&gt;
| haproxy-01 et haproxy-02&lt;br /&gt;
|-&lt;br /&gt;
| Applications suivies&lt;br /&gt;
| Drupal Internet et Drupal Salle de lecture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Configuration HAProxy ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
# AD64 MATOMO&lt;br /&gt;
acl host_ad64_matomo hdr(host),host_only -i ad64-matomo.pleade.com&lt;br /&gt;
&lt;br /&gt;
# Points de collecte accessibles publiquement&lt;br /&gt;
acl ad64_matomo_tracking path -i /matomo.js /matomo.php&lt;br /&gt;
&lt;br /&gt;
# Administration réservée à AJLSM&lt;br /&gt;
http-request deny if host_ad64_matomo !allowed_ajlsm !ad64_matomo_tracking&lt;br /&gt;
&lt;br /&gt;
http-request redirect scheme https if host_ad64_matomo !{ ssl_fc }&lt;br /&gt;
&lt;br /&gt;
use_backend back_ssl_ad64_matomo if host_ad64_matomo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Backend HTTPS existant :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
backend back_ssl_ad64_matomo&lt;br /&gt;
    server SSLAD64MATOMO 10.0.0.41:443 check ssl verify none sni str(ad64-matomo.pleade.com)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;ancien backend HTTP `back_ad64_matomo` a été conservé sans modification, bien qu&#039;il ne soit plus utilisé par ce routage.&lt;br /&gt;
&lt;br /&gt;
=== Résultats des tests ===&lt;br /&gt;
&lt;br /&gt;
Les vérifications réalisées le 20 octobre 2026 depuis une connexion extérieure au bureau ont donné :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Test&lt;br /&gt;
! Résultat&lt;br /&gt;
|-&lt;br /&gt;
| https://ad64-matomo.pleade.com/matomo.js&lt;br /&gt;
| HTTP 200&lt;br /&gt;
|-&lt;br /&gt;
| https://ad64-matomo.pleade.com/matomo.php&lt;br /&gt;
| HTTP 200&lt;br /&gt;
|-&lt;br /&gt;
| https://ad64-matomo.pleade.com/&lt;br /&gt;
| HTTP 403&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les visites Drupal Internet et Salle de lecture avaient également été enregistrées dans MariaDB, avec les identifiants Matomo 2 et 3.&lt;br /&gt;
&lt;br /&gt;
La collecte et la restriction d&#039;accès ont donc été vérifiées.&lt;br /&gt;
&lt;br /&gt;
== 11. Points de vigilance ==&lt;br /&gt;
&lt;br /&gt;
* Ne jamais ouvrir toute l&#039;interface Matomo à Internet uniquement pour permettre la collecte.&lt;br /&gt;
* Ne pas autoriser systématiquement les adresses IP du client à accéder à l&#039;administration.&lt;br /&gt;
* Ne pas bloquer les points de collecte nécessaires aux visiteurs.&lt;br /&gt;
* Ne pas modifier directement les fichiers HAProxy générés par Ansible.&lt;br /&gt;
* Tester depuis une véritable connexion extérieure.&lt;br /&gt;
* Vérifier le certificat HTTPS et son renouvellement.&lt;br /&gt;
* Vérifier que la collecte réelle fonctionne, au-delà du simple chargement du JavaScript.&lt;br /&gt;
&lt;br /&gt;
== 12. Maintenance et diagnostic ==&lt;br /&gt;
&lt;br /&gt;
En cas d&#039;anomalie, vérifier successivement :&lt;br /&gt;
&lt;br /&gt;
# La résolution DNS du domaine Matomo.&lt;br /&gt;
# Le certificat HTTPS présenté par HAProxy.&lt;br /&gt;
# La correspondance de l&#039;ACL `host`.&lt;br /&gt;
# Les règles `http-request deny`.&lt;br /&gt;
# Les chemins autorisés pour le suivi.&lt;br /&gt;
# L&#039;état du backend HAProxy.&lt;br /&gt;
# La disponibilité d&#039;Apache et PHP-FPM sur la VM.&lt;br /&gt;
# La réception effective des visites dans Matomo.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Debug]] et [[Matomo/Maintenance]].&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=Matomo/HAProxy&amp;diff=6513</id>
		<title>Matomo/HAProxy</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=Matomo/HAProxy&amp;diff=6513"/>
		<updated>2026-10-20T10:44:16Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : /* 7. Déploiement avec Ansible */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Publication et sécurisation de Matomo avec HAProxy =&lt;br /&gt;
&lt;br /&gt;
== Objectif ==&lt;br /&gt;
&lt;br /&gt;
Cette procédure décrit la publication d&#039;une instance Matomo derrière les répartiteurs HAProxy d&#039;AJLSM.&lt;br /&gt;
&lt;br /&gt;
Elle permet de :&lt;br /&gt;
&lt;br /&gt;
* Publier Matomo en HTTPS.&lt;br /&gt;
* Autoriser les requêtes de collecte des statistiques provenant des visiteurs.&lt;br /&gt;
* Réserver l&#039;interface d&#039;administration aux adresses IP autorisées.&lt;br /&gt;
* Déployer une configuration identique sur les deux HAProxy à l&#039;aide d&#039;Ansible.&lt;br /&gt;
* Vérifier le fonctionnement depuis une connexion extérieure.&lt;br /&gt;
&lt;br /&gt;
Cette procédure complète :&lt;br /&gt;
&lt;br /&gt;
* [[Matomo/Installation]]&lt;br /&gt;
* [[Matomo/Apache]]&lt;br /&gt;
* [[Matomo/Drupal]]&lt;br /&gt;
* [[Matomo/Debug]]&lt;br /&gt;
&lt;br /&gt;
== 1. Architecture ==&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;infrastructure AJLSM, le trafic suit généralement le chemin suivant :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Navigateur du visiteur&lt;br /&gt;
        |&lt;br /&gt;
        | HTTPS&lt;br /&gt;
        v&lt;br /&gt;
HAProxy (haproxy-01 / haproxy-02)&lt;br /&gt;
        |&lt;br /&gt;
        | HTTPS ou HTTP interne&lt;br /&gt;
        v&lt;br /&gt;
VM applicative&lt;br /&gt;
        |&lt;br /&gt;
        v&lt;br /&gt;
Apache + PHP-FPM + Matomo&lt;br /&gt;
        |&lt;br /&gt;
        v&lt;br /&gt;
MariaDB&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le navigateur charge le JavaScript Matomo et transmet les données de fréquentation au serveur Matomo.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; la collecte des statistiques doit fonctionner pour les visiteurs extérieurs, même lorsque l&#039;interface d&#039;administration Matomo est réservée à AJLSM.&lt;br /&gt;
&lt;br /&gt;
== 2. Prérequis ==&lt;br /&gt;
&lt;br /&gt;
Avant de modifier HAProxy, vérifier :&lt;br /&gt;
&lt;br /&gt;
* Que Matomo fonctionne sur la VM applicative.&lt;br /&gt;
* Que le VirtualHost Apache est configuré.&lt;br /&gt;
* Que le nom DNS public de Matomo est défini.&lt;br /&gt;
* Que le certificat HTTPS public est disponible sur HAProxy.&lt;br /&gt;
* Que le backend Matomo est joignable depuis les répartiteurs.&lt;br /&gt;
* Que l&#039;adresse IP ou le réseau autorisé pour l&#039;administration est connu.&lt;br /&gt;
&lt;br /&gt;
La configuration HAProxy est gérée par Ansible. Les modifications doivent être réalisées dans les fichiers sources du dépôt `ansible-ajlsm`, et non directement dans `/etc/haproxy/haproxy.cfg` sur les serveurs.&lt;br /&gt;
&lt;br /&gt;
== 3. Paramètres à personnaliser ==&lt;br /&gt;
&lt;br /&gt;
Pour chaque nouvelle installation, identifier les paramètres suivants :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Paramètre&lt;br /&gt;
! Exemple&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| Domaine Matomo&lt;br /&gt;
| matomo.exemple.fr&lt;br /&gt;
| Nom DNS public de Matomo&lt;br /&gt;
|-&lt;br /&gt;
| Backend&lt;br /&gt;
| back_ssl_projet_matomo&lt;br /&gt;
| Nom du backend HAProxy&lt;br /&gt;
|-&lt;br /&gt;
| Adresse de la VM&lt;br /&gt;
| 10.0.0.X&lt;br /&gt;
| Adresse privée de la VM hébergeant Matomo&lt;br /&gt;
|-&lt;br /&gt;
| Port backend&lt;br /&gt;
| 443&lt;br /&gt;
| Port HTTPS interne, si utilisé&lt;br /&gt;
|-&lt;br /&gt;
| ACL des administrateurs&lt;br /&gt;
| allowed_ajlsm&lt;br /&gt;
| Adresses IP autorisées à accéder à l&#039;interface&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 4. Configuration des ACL ==&lt;br /&gt;
&lt;br /&gt;
=== Principe ===&lt;br /&gt;
&lt;br /&gt;
Deux chemins sont nécessaires au suivi Matomo standard :&lt;br /&gt;
&lt;br /&gt;
* `/matomo.js` : chargement du JavaScript de suivi.&lt;br /&gt;
* `/matomo.php` : réception des données de fréquentation.&lt;br /&gt;
&lt;br /&gt;
Ces deux chemins doivent rester accessibles publiquement.&lt;br /&gt;
&lt;br /&gt;
Les autres chemins de l&#039;interface Matomo sont réservés aux adresses IP autorisées.&lt;br /&gt;
&lt;br /&gt;
=== Exemple générique ===&lt;br /&gt;
&lt;br /&gt;
Ajouter les règles suivantes dans le frontend HAProxy approprié :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;haproxy&amp;quot;&amp;gt;&lt;br /&gt;
# MATOMO - PROJET&lt;br /&gt;
acl host_projet_matomo hdr(host),host_only -i matomo.exemple.fr&lt;br /&gt;
&lt;br /&gt;
# Ressources de collecte accessibles publiquement&lt;br /&gt;
acl projet_matomo_tracking path -i /matomo.js /matomo.php&lt;br /&gt;
&lt;br /&gt;
# Interface Matomo réservée à AJLSM&lt;br /&gt;
http-request deny if host_projet_matomo !allowed_ajlsm !projet_matomo_tracking&lt;br /&gt;
&lt;br /&gt;
# Redirection HTTP vers HTTPS&lt;br /&gt;
http-request redirect scheme https if host_projet_matomo !{ ssl_fc }&lt;br /&gt;
&lt;br /&gt;
# Routage vers le backend Matomo&lt;br /&gt;
use_backend back_ssl_projet_matomo if host_projet_matomo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; cet exemple utilise l&#039;ACL `allowed_ajlsm` déjà présente dans l&#039;infrastructure AJLSM. Vérifier son existence et son contenu avant de déployer la configuration.&lt;br /&gt;
&lt;br /&gt;
L&#039;ACL `path -i` effectue une correspondance exacte des chemins. Elle ne rend pas accessibles les autres pages de l&#039;administration Matomo.&lt;br /&gt;
&lt;br /&gt;
Cette configuration est adaptée au suivi JavaScript standard. Si des fonctionnalités supplémentaires nécessitent d&#039;autres points d&#039;accès, leurs chemins doivent être étudiés séparément avant toute ouverture.&lt;br /&gt;
&lt;br /&gt;
== 5. Configuration du backend ==&lt;br /&gt;
&lt;br /&gt;
=== Exemple HTTPS ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
backend back_ssl_projet_matomo&lt;br /&gt;
    server SSLPROJETMATOMO 10.0.0.X:443 check ssl verify none sni str(matomo.exemple.fr)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remplacer l&#039;adresse IP, le nom du serveur et le nom de domaine par les paramètres du projet.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Sécurité :&#039;&#039;&#039; `verify none` désactive la vérification du certificat présenté par le backend. Cette configuration existe sur AD64, mais ne doit pas être considérée comme une recommandation générale.&lt;br /&gt;
&lt;br /&gt;
Pour une nouvelle installation, privilégier une validation TLS du backend avec une autorité de certification appropriée lorsque l&#039;architecture le permet.&lt;br /&gt;
&lt;br /&gt;
=== Backend HTTP ===&lt;br /&gt;
&lt;br /&gt;
Un backend HTTP peut également être utilisé sur un réseau interne maîtrisé :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
backend back_projet_matomo&lt;br /&gt;
    server PROJETMATOMO 10.0.0.X:80 check&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le choix entre HTTP et HTTPS interne dépend de l&#039;architecture du projet et des exigences de sécurité.&lt;br /&gt;
&lt;br /&gt;
== 6. Certificats HTTPS ==&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;infrastructure AJLSM, les certificats publics HAProxy peuvent être gérés par `acme.sh`.&lt;br /&gt;
&lt;br /&gt;
Sur les serveurs HAProxy concernés, vérifier :&lt;br /&gt;
&lt;br /&gt;
* L&#039;existence du certificat pour le domaine Matomo.&lt;br /&gt;
* Sa date d&#039;expiration.&lt;br /&gt;
* La configuration de renouvellement automatique.&lt;br /&gt;
* Le mécanisme de déploiement du certificat dans HAProxy.&lt;br /&gt;
&lt;br /&gt;
Exemple de vérification depuis un poste client :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
openssl s_client \&lt;br /&gt;
  -connect matomo.exemple.fr:443 \&lt;br /&gt;
  -servername matomo.exemple.fr &amp;lt;/dev/null 2&amp;gt;/dev/null \&lt;br /&gt;
  | openssl x509 -noout -subject -issuer -dates&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La présence d&#039;une tâche automatique de renouvellement ne garantit pas à elle seule que le déploiement d&#039;un nouveau certificat fonctionnera. Le renouvellement et le rechargement effectif du certificat doivent être contrôlés.&lt;br /&gt;
&lt;br /&gt;
== 7. Déploiement avec Ansible ==&lt;br /&gt;
Voir aussi : [[WAF_2026#Ansible|WAF 2026]]&lt;br /&gt;
=== Modification ===&lt;br /&gt;
&lt;br /&gt;
Depuis le Mac d&#039;administration :&lt;br /&gt;
&lt;br /&gt;
# Ouvrir le dépôt `ansible-ajlsm`.&lt;br /&gt;
# Modifier la configuration HAProxy dans les sources Ansible.&lt;br /&gt;
# Ajouter les ACL et le routage du nouveau domaine Matomo.&lt;br /&gt;
# Vérifier que les backends sont définis.&lt;br /&gt;
# Ne pas modifier directement les configurations générées sur les deux serveurs.&lt;br /&gt;
&lt;br /&gt;
=== Vérification de la syntaxe du playbook ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer --syntax-check&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Simulation du déploiement ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer --check --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier :&lt;br /&gt;
&lt;br /&gt;
* Que les modifications sont identiques sur les deux HAProxy.&lt;br /&gt;
* Que seuls les blocs attendus changent.&lt;br /&gt;
* Qu&#039;aucune configuration d&#039;un autre client n&#039;est modifiée.&lt;br /&gt;
* Qu&#039;aucune erreur n&#039;est signalée.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; le mode `--check` est une simulation. Il ne garantit pas à lui seul le succès du déploiement réel ni le comportement des ACL en production.&lt;br /&gt;
&lt;br /&gt;
=== Déploiement réel ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier le résultat du playbook sur les deux serveurs.&lt;br /&gt;
&lt;br /&gt;
Si le playbook prévoit un redémarrage ou un rechargement HAProxy, contrôler ensuite que les services restent actifs et que les applications existantes répondent normalement.&lt;br /&gt;
&lt;br /&gt;
== 8. Vérification depuis une connexion extérieure ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; effectuer les tests depuis une connexion qui n&#039;utilise ni l&#039;adresse IP publique du bureau ni le VPN AJLSM.&lt;br /&gt;
&lt;br /&gt;
Une connexion autorisée ne permet pas de vérifier correctement le refus d&#039;accès à l&#039;administration.&lt;br /&gt;
&lt;br /&gt;
=== Tester les ressources de suivi ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
MATOMO_URL=&amp;quot;https://matomo.exemple.fr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
for RESOURCE in matomo.js matomo.php; do&lt;br /&gt;
    echo &amp;quot;===== /$RESOURCE =====&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    curl -sS -o /dev/null -w &amp;quot;HTTP %{http_code}\n&amp;quot; \&lt;br /&gt;
        &amp;quot;$MATOMO_URL/$RESOURCE&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultats attendus pour l&#039;installation standard :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Ressource&lt;br /&gt;
! Résultat attendu&lt;br /&gt;
|-&lt;br /&gt;
| /matomo.js&lt;br /&gt;
| HTTP 200&lt;br /&gt;
|-&lt;br /&gt;
| /matomo.php&lt;br /&gt;
| Accessible sans HTTP 403 HAProxy&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Remarque :&#039;&#039;&#039; une réponse HTTP 200 de `matomo.php` sans paramètres de suivi ne constitue pas une preuve de collecte effective.&lt;br /&gt;
&lt;br /&gt;
=== Tester la protection de l&#039;administration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -sS -o /dev/null -w &amp;quot;HTTP %{http_code}\n&amp;quot; \&lt;br /&gt;
    &amp;quot;$MATOMO_URL/&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat attendu depuis une adresse IP extérieure non autorisée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
HTTP 403&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tester depuis une adresse autorisée ===&lt;br /&gt;
&lt;br /&gt;
Depuis le réseau AJLSM ou un accès VPN autorisé, vérifier que l&#039;interface Matomo reste accessible et que l&#039;authentification Matomo fonctionne.&lt;br /&gt;
&lt;br /&gt;
== 9. Vérification de la collecte ==&lt;br /&gt;
&lt;br /&gt;
Une fois les règles HAProxy appliquées :&lt;br /&gt;
&lt;br /&gt;
# Ouvrir une application Drupal ou Pleade suivie par Matomo.&lt;br /&gt;
# Naviguer sur plusieurs pages publiques.&lt;br /&gt;
# Vérifier l&#039;envoi des requêtes de suivi dans les outils réseau du navigateur.&lt;br /&gt;
# Vérifier l&#039;apparition des visites dans l&#039;interface Matomo.&lt;br /&gt;
&lt;br /&gt;
Pour une vérification directe en base :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT&lt;br /&gt;
    idsite,&lt;br /&gt;
    COUNT(*) AS visites,&lt;br /&gt;
    MAX(visit_last_action_time) AS derniere_activite&lt;br /&gt;
FROM matomo_log_visit&lt;br /&gt;
GROUP BY idsite;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette requête doit être exécutée dans la base Matomo avec un compte disposant des droits nécessaires.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Drupal]] et [[Matomo/Debug]].&lt;br /&gt;
&lt;br /&gt;
== 10. Exemple validé : AD64 — octobre 2026 ==&lt;br /&gt;
&lt;br /&gt;
=== Environnement ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Élément&lt;br /&gt;
! Valeur&lt;br /&gt;
|-&lt;br /&gt;
| Serveur Matomo&lt;br /&gt;
| ad64&lt;br /&gt;
|-&lt;br /&gt;
| Domaine&lt;br /&gt;
| ad64-matomo.pleade.com&lt;br /&gt;
|-&lt;br /&gt;
| Adresse privée de la VM&lt;br /&gt;
| 10.0.0.41&lt;br /&gt;
|-&lt;br /&gt;
| Backend HTTPS&lt;br /&gt;
| back_ssl_ad64_matomo&lt;br /&gt;
|-&lt;br /&gt;
| Répartiteurs&lt;br /&gt;
| haproxy-01 et haproxy-02&lt;br /&gt;
|-&lt;br /&gt;
| Applications suivies&lt;br /&gt;
| Drupal Internet et Drupal Salle de lecture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Configuration HAProxy ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
# AD64 MATOMO&lt;br /&gt;
acl host_ad64_matomo hdr(host),host_only -i ad64-matomo.pleade.com&lt;br /&gt;
&lt;br /&gt;
# Points de collecte accessibles publiquement&lt;br /&gt;
acl ad64_matomo_tracking path -i /matomo.js /matomo.php&lt;br /&gt;
&lt;br /&gt;
# Administration réservée à AJLSM&lt;br /&gt;
http-request deny if host_ad64_matomo !allowed_ajlsm !ad64_matomo_tracking&lt;br /&gt;
&lt;br /&gt;
http-request redirect scheme https if host_ad64_matomo !{ ssl_fc }&lt;br /&gt;
&lt;br /&gt;
use_backend back_ssl_ad64_matomo if host_ad64_matomo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Backend HTTPS existant :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
backend back_ssl_ad64_matomo&lt;br /&gt;
    server SSLAD64MATOMO 10.0.0.41:443 check ssl verify none sni str(ad64-matomo.pleade.com)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;ancien backend HTTP `back_ad64_matomo` a été conservé sans modification, bien qu&#039;il ne soit plus utilisé par ce routage.&lt;br /&gt;
&lt;br /&gt;
=== Résultats des tests ===&lt;br /&gt;
&lt;br /&gt;
Les vérifications réalisées le 20 octobre 2026 depuis une connexion extérieure au bureau ont donné :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Test&lt;br /&gt;
! Résultat&lt;br /&gt;
|-&lt;br /&gt;
| https://ad64-matomo.pleade.com/matomo.js&lt;br /&gt;
| HTTP 200&lt;br /&gt;
|-&lt;br /&gt;
| https://ad64-matomo.pleade.com/matomo.php&lt;br /&gt;
| HTTP 200&lt;br /&gt;
|-&lt;br /&gt;
| https://ad64-matomo.pleade.com/&lt;br /&gt;
| HTTP 403&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les visites Drupal Internet et Salle de lecture avaient également été enregistrées dans MariaDB, avec les identifiants Matomo 2 et 3.&lt;br /&gt;
&lt;br /&gt;
La collecte et la restriction d&#039;accès ont donc été vérifiées.&lt;br /&gt;
&lt;br /&gt;
== 11. Points de vigilance ==&lt;br /&gt;
&lt;br /&gt;
* Ne jamais ouvrir toute l&#039;interface Matomo à Internet uniquement pour permettre la collecte.&lt;br /&gt;
* Ne pas autoriser systématiquement les adresses IP du client à accéder à l&#039;administration.&lt;br /&gt;
* Ne pas bloquer les points de collecte nécessaires aux visiteurs.&lt;br /&gt;
* Ne pas modifier directement les fichiers HAProxy générés par Ansible.&lt;br /&gt;
* Tester depuis une véritable connexion extérieure.&lt;br /&gt;
* Vérifier le certificat HTTPS et son renouvellement.&lt;br /&gt;
* Vérifier que la collecte réelle fonctionne, au-delà du simple chargement du JavaScript.&lt;br /&gt;
&lt;br /&gt;
== 12. Maintenance et diagnostic ==&lt;br /&gt;
&lt;br /&gt;
En cas d&#039;anomalie, vérifier successivement :&lt;br /&gt;
&lt;br /&gt;
# La résolution DNS du domaine Matomo.&lt;br /&gt;
# Le certificat HTTPS présenté par HAProxy.&lt;br /&gt;
# La correspondance de l&#039;ACL `host`.&lt;br /&gt;
# Les règles `http-request deny`.&lt;br /&gt;
# Les chemins autorisés pour le suivi.&lt;br /&gt;
# L&#039;état du backend HAProxy.&lt;br /&gt;
# La disponibilité d&#039;Apache et PHP-FPM sur la VM.&lt;br /&gt;
# La réception effective des visites dans Matomo.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Debug]] et [[Matomo/Maintenance]].&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=Matomo/HAProxy&amp;diff=6512</id>
		<title>Matomo/HAProxy</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=Matomo/HAProxy&amp;diff=6512"/>
		<updated>2026-10-20T10:43:40Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : /* 7. Déploiement avec Ansible */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Publication et sécurisation de Matomo avec HAProxy =&lt;br /&gt;
&lt;br /&gt;
== Objectif ==&lt;br /&gt;
&lt;br /&gt;
Cette procédure décrit la publication d&#039;une instance Matomo derrière les répartiteurs HAProxy d&#039;AJLSM.&lt;br /&gt;
&lt;br /&gt;
Elle permet de :&lt;br /&gt;
&lt;br /&gt;
* Publier Matomo en HTTPS.&lt;br /&gt;
* Autoriser les requêtes de collecte des statistiques provenant des visiteurs.&lt;br /&gt;
* Réserver l&#039;interface d&#039;administration aux adresses IP autorisées.&lt;br /&gt;
* Déployer une configuration identique sur les deux HAProxy à l&#039;aide d&#039;Ansible.&lt;br /&gt;
* Vérifier le fonctionnement depuis une connexion extérieure.&lt;br /&gt;
&lt;br /&gt;
Cette procédure complète :&lt;br /&gt;
&lt;br /&gt;
* [[Matomo/Installation]]&lt;br /&gt;
* [[Matomo/Apache]]&lt;br /&gt;
* [[Matomo/Drupal]]&lt;br /&gt;
* [[Matomo/Debug]]&lt;br /&gt;
&lt;br /&gt;
== 1. Architecture ==&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;infrastructure AJLSM, le trafic suit généralement le chemin suivant :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Navigateur du visiteur&lt;br /&gt;
        |&lt;br /&gt;
        | HTTPS&lt;br /&gt;
        v&lt;br /&gt;
HAProxy (haproxy-01 / haproxy-02)&lt;br /&gt;
        |&lt;br /&gt;
        | HTTPS ou HTTP interne&lt;br /&gt;
        v&lt;br /&gt;
VM applicative&lt;br /&gt;
        |&lt;br /&gt;
        v&lt;br /&gt;
Apache + PHP-FPM + Matomo&lt;br /&gt;
        |&lt;br /&gt;
        v&lt;br /&gt;
MariaDB&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le navigateur charge le JavaScript Matomo et transmet les données de fréquentation au serveur Matomo.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; la collecte des statistiques doit fonctionner pour les visiteurs extérieurs, même lorsque l&#039;interface d&#039;administration Matomo est réservée à AJLSM.&lt;br /&gt;
&lt;br /&gt;
== 2. Prérequis ==&lt;br /&gt;
&lt;br /&gt;
Avant de modifier HAProxy, vérifier :&lt;br /&gt;
&lt;br /&gt;
* Que Matomo fonctionne sur la VM applicative.&lt;br /&gt;
* Que le VirtualHost Apache est configuré.&lt;br /&gt;
* Que le nom DNS public de Matomo est défini.&lt;br /&gt;
* Que le certificat HTTPS public est disponible sur HAProxy.&lt;br /&gt;
* Que le backend Matomo est joignable depuis les répartiteurs.&lt;br /&gt;
* Que l&#039;adresse IP ou le réseau autorisé pour l&#039;administration est connu.&lt;br /&gt;
&lt;br /&gt;
La configuration HAProxy est gérée par Ansible. Les modifications doivent être réalisées dans les fichiers sources du dépôt `ansible-ajlsm`, et non directement dans `/etc/haproxy/haproxy.cfg` sur les serveurs.&lt;br /&gt;
&lt;br /&gt;
== 3. Paramètres à personnaliser ==&lt;br /&gt;
&lt;br /&gt;
Pour chaque nouvelle installation, identifier les paramètres suivants :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Paramètre&lt;br /&gt;
! Exemple&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| Domaine Matomo&lt;br /&gt;
| matomo.exemple.fr&lt;br /&gt;
| Nom DNS public de Matomo&lt;br /&gt;
|-&lt;br /&gt;
| Backend&lt;br /&gt;
| back_ssl_projet_matomo&lt;br /&gt;
| Nom du backend HAProxy&lt;br /&gt;
|-&lt;br /&gt;
| Adresse de la VM&lt;br /&gt;
| 10.0.0.X&lt;br /&gt;
| Adresse privée de la VM hébergeant Matomo&lt;br /&gt;
|-&lt;br /&gt;
| Port backend&lt;br /&gt;
| 443&lt;br /&gt;
| Port HTTPS interne, si utilisé&lt;br /&gt;
|-&lt;br /&gt;
| ACL des administrateurs&lt;br /&gt;
| allowed_ajlsm&lt;br /&gt;
| Adresses IP autorisées à accéder à l&#039;interface&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 4. Configuration des ACL ==&lt;br /&gt;
&lt;br /&gt;
=== Principe ===&lt;br /&gt;
&lt;br /&gt;
Deux chemins sont nécessaires au suivi Matomo standard :&lt;br /&gt;
&lt;br /&gt;
* `/matomo.js` : chargement du JavaScript de suivi.&lt;br /&gt;
* `/matomo.php` : réception des données de fréquentation.&lt;br /&gt;
&lt;br /&gt;
Ces deux chemins doivent rester accessibles publiquement.&lt;br /&gt;
&lt;br /&gt;
Les autres chemins de l&#039;interface Matomo sont réservés aux adresses IP autorisées.&lt;br /&gt;
&lt;br /&gt;
=== Exemple générique ===&lt;br /&gt;
&lt;br /&gt;
Ajouter les règles suivantes dans le frontend HAProxy approprié :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;haproxy&amp;quot;&amp;gt;&lt;br /&gt;
# MATOMO - PROJET&lt;br /&gt;
acl host_projet_matomo hdr(host),host_only -i matomo.exemple.fr&lt;br /&gt;
&lt;br /&gt;
# Ressources de collecte accessibles publiquement&lt;br /&gt;
acl projet_matomo_tracking path -i /matomo.js /matomo.php&lt;br /&gt;
&lt;br /&gt;
# Interface Matomo réservée à AJLSM&lt;br /&gt;
http-request deny if host_projet_matomo !allowed_ajlsm !projet_matomo_tracking&lt;br /&gt;
&lt;br /&gt;
# Redirection HTTP vers HTTPS&lt;br /&gt;
http-request redirect scheme https if host_projet_matomo !{ ssl_fc }&lt;br /&gt;
&lt;br /&gt;
# Routage vers le backend Matomo&lt;br /&gt;
use_backend back_ssl_projet_matomo if host_projet_matomo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; cet exemple utilise l&#039;ACL `allowed_ajlsm` déjà présente dans l&#039;infrastructure AJLSM. Vérifier son existence et son contenu avant de déployer la configuration.&lt;br /&gt;
&lt;br /&gt;
L&#039;ACL `path -i` effectue une correspondance exacte des chemins. Elle ne rend pas accessibles les autres pages de l&#039;administration Matomo.&lt;br /&gt;
&lt;br /&gt;
Cette configuration est adaptée au suivi JavaScript standard. Si des fonctionnalités supplémentaires nécessitent d&#039;autres points d&#039;accès, leurs chemins doivent être étudiés séparément avant toute ouverture.&lt;br /&gt;
&lt;br /&gt;
== 5. Configuration du backend ==&lt;br /&gt;
&lt;br /&gt;
=== Exemple HTTPS ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
backend back_ssl_projet_matomo&lt;br /&gt;
    server SSLPROJETMATOMO 10.0.0.X:443 check ssl verify none sni str(matomo.exemple.fr)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remplacer l&#039;adresse IP, le nom du serveur et le nom de domaine par les paramètres du projet.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Sécurité :&#039;&#039;&#039; `verify none` désactive la vérification du certificat présenté par le backend. Cette configuration existe sur AD64, mais ne doit pas être considérée comme une recommandation générale.&lt;br /&gt;
&lt;br /&gt;
Pour une nouvelle installation, privilégier une validation TLS du backend avec une autorité de certification appropriée lorsque l&#039;architecture le permet.&lt;br /&gt;
&lt;br /&gt;
=== Backend HTTP ===&lt;br /&gt;
&lt;br /&gt;
Un backend HTTP peut également être utilisé sur un réseau interne maîtrisé :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
backend back_projet_matomo&lt;br /&gt;
    server PROJETMATOMO 10.0.0.X:80 check&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le choix entre HTTP et HTTPS interne dépend de l&#039;architecture du projet et des exigences de sécurité.&lt;br /&gt;
&lt;br /&gt;
== 6. Certificats HTTPS ==&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;infrastructure AJLSM, les certificats publics HAProxy peuvent être gérés par `acme.sh`.&lt;br /&gt;
&lt;br /&gt;
Sur les serveurs HAProxy concernés, vérifier :&lt;br /&gt;
&lt;br /&gt;
* L&#039;existence du certificat pour le domaine Matomo.&lt;br /&gt;
* Sa date d&#039;expiration.&lt;br /&gt;
* La configuration de renouvellement automatique.&lt;br /&gt;
* Le mécanisme de déploiement du certificat dans HAProxy.&lt;br /&gt;
&lt;br /&gt;
Exemple de vérification depuis un poste client :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
openssl s_client \&lt;br /&gt;
  -connect matomo.exemple.fr:443 \&lt;br /&gt;
  -servername matomo.exemple.fr &amp;lt;/dev/null 2&amp;gt;/dev/null \&lt;br /&gt;
  | openssl x509 -noout -subject -issuer -dates&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La présence d&#039;une tâche automatique de renouvellement ne garantit pas à elle seule que le déploiement d&#039;un nouveau certificat fonctionnera. Le renouvellement et le rechargement effectif du certificat doivent être contrôlés.&lt;br /&gt;
&lt;br /&gt;
== 7. Déploiement avec Ansible ==&lt;br /&gt;
Voir aussi : [[WAF 2026|WAF_2026#Ansible]]&lt;br /&gt;
=== Modification ===&lt;br /&gt;
&lt;br /&gt;
Depuis le Mac d&#039;administration :&lt;br /&gt;
&lt;br /&gt;
# Ouvrir le dépôt `ansible-ajlsm`.&lt;br /&gt;
# Modifier la configuration HAProxy dans les sources Ansible.&lt;br /&gt;
# Ajouter les ACL et le routage du nouveau domaine Matomo.&lt;br /&gt;
# Vérifier que les backends sont définis.&lt;br /&gt;
# Ne pas modifier directement les configurations générées sur les deux serveurs.&lt;br /&gt;
&lt;br /&gt;
=== Vérification de la syntaxe du playbook ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer --syntax-check&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Simulation du déploiement ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer --check --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier :&lt;br /&gt;
&lt;br /&gt;
* Que les modifications sont identiques sur les deux HAProxy.&lt;br /&gt;
* Que seuls les blocs attendus changent.&lt;br /&gt;
* Qu&#039;aucune configuration d&#039;un autre client n&#039;est modifiée.&lt;br /&gt;
* Qu&#039;aucune erreur n&#039;est signalée.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; le mode `--check` est une simulation. Il ne garantit pas à lui seul le succès du déploiement réel ni le comportement des ACL en production.&lt;br /&gt;
&lt;br /&gt;
=== Déploiement réel ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier le résultat du playbook sur les deux serveurs.&lt;br /&gt;
&lt;br /&gt;
Si le playbook prévoit un redémarrage ou un rechargement HAProxy, contrôler ensuite que les services restent actifs et que les applications existantes répondent normalement.&lt;br /&gt;
&lt;br /&gt;
== 8. Vérification depuis une connexion extérieure ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; effectuer les tests depuis une connexion qui n&#039;utilise ni l&#039;adresse IP publique du bureau ni le VPN AJLSM.&lt;br /&gt;
&lt;br /&gt;
Une connexion autorisée ne permet pas de vérifier correctement le refus d&#039;accès à l&#039;administration.&lt;br /&gt;
&lt;br /&gt;
=== Tester les ressources de suivi ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
MATOMO_URL=&amp;quot;https://matomo.exemple.fr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
for RESOURCE in matomo.js matomo.php; do&lt;br /&gt;
    echo &amp;quot;===== /$RESOURCE =====&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    curl -sS -o /dev/null -w &amp;quot;HTTP %{http_code}\n&amp;quot; \&lt;br /&gt;
        &amp;quot;$MATOMO_URL/$RESOURCE&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultats attendus pour l&#039;installation standard :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Ressource&lt;br /&gt;
! Résultat attendu&lt;br /&gt;
|-&lt;br /&gt;
| /matomo.js&lt;br /&gt;
| HTTP 200&lt;br /&gt;
|-&lt;br /&gt;
| /matomo.php&lt;br /&gt;
| Accessible sans HTTP 403 HAProxy&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Remarque :&#039;&#039;&#039; une réponse HTTP 200 de `matomo.php` sans paramètres de suivi ne constitue pas une preuve de collecte effective.&lt;br /&gt;
&lt;br /&gt;
=== Tester la protection de l&#039;administration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -sS -o /dev/null -w &amp;quot;HTTP %{http_code}\n&amp;quot; \&lt;br /&gt;
    &amp;quot;$MATOMO_URL/&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat attendu depuis une adresse IP extérieure non autorisée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
HTTP 403&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tester depuis une adresse autorisée ===&lt;br /&gt;
&lt;br /&gt;
Depuis le réseau AJLSM ou un accès VPN autorisé, vérifier que l&#039;interface Matomo reste accessible et que l&#039;authentification Matomo fonctionne.&lt;br /&gt;
&lt;br /&gt;
== 9. Vérification de la collecte ==&lt;br /&gt;
&lt;br /&gt;
Une fois les règles HAProxy appliquées :&lt;br /&gt;
&lt;br /&gt;
# Ouvrir une application Drupal ou Pleade suivie par Matomo.&lt;br /&gt;
# Naviguer sur plusieurs pages publiques.&lt;br /&gt;
# Vérifier l&#039;envoi des requêtes de suivi dans les outils réseau du navigateur.&lt;br /&gt;
# Vérifier l&#039;apparition des visites dans l&#039;interface Matomo.&lt;br /&gt;
&lt;br /&gt;
Pour une vérification directe en base :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT&lt;br /&gt;
    idsite,&lt;br /&gt;
    COUNT(*) AS visites,&lt;br /&gt;
    MAX(visit_last_action_time) AS derniere_activite&lt;br /&gt;
FROM matomo_log_visit&lt;br /&gt;
GROUP BY idsite;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette requête doit être exécutée dans la base Matomo avec un compte disposant des droits nécessaires.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Drupal]] et [[Matomo/Debug]].&lt;br /&gt;
&lt;br /&gt;
== 10. Exemple validé : AD64 — octobre 2026 ==&lt;br /&gt;
&lt;br /&gt;
=== Environnement ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Élément&lt;br /&gt;
! Valeur&lt;br /&gt;
|-&lt;br /&gt;
| Serveur Matomo&lt;br /&gt;
| ad64&lt;br /&gt;
|-&lt;br /&gt;
| Domaine&lt;br /&gt;
| ad64-matomo.pleade.com&lt;br /&gt;
|-&lt;br /&gt;
| Adresse privée de la VM&lt;br /&gt;
| 10.0.0.41&lt;br /&gt;
|-&lt;br /&gt;
| Backend HTTPS&lt;br /&gt;
| back_ssl_ad64_matomo&lt;br /&gt;
|-&lt;br /&gt;
| Répartiteurs&lt;br /&gt;
| haproxy-01 et haproxy-02&lt;br /&gt;
|-&lt;br /&gt;
| Applications suivies&lt;br /&gt;
| Drupal Internet et Drupal Salle de lecture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Configuration HAProxy ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
# AD64 MATOMO&lt;br /&gt;
acl host_ad64_matomo hdr(host),host_only -i ad64-matomo.pleade.com&lt;br /&gt;
&lt;br /&gt;
# Points de collecte accessibles publiquement&lt;br /&gt;
acl ad64_matomo_tracking path -i /matomo.js /matomo.php&lt;br /&gt;
&lt;br /&gt;
# Administration réservée à AJLSM&lt;br /&gt;
http-request deny if host_ad64_matomo !allowed_ajlsm !ad64_matomo_tracking&lt;br /&gt;
&lt;br /&gt;
http-request redirect scheme https if host_ad64_matomo !{ ssl_fc }&lt;br /&gt;
&lt;br /&gt;
use_backend back_ssl_ad64_matomo if host_ad64_matomo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Backend HTTPS existant :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
backend back_ssl_ad64_matomo&lt;br /&gt;
    server SSLAD64MATOMO 10.0.0.41:443 check ssl verify none sni str(ad64-matomo.pleade.com)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;ancien backend HTTP `back_ad64_matomo` a été conservé sans modification, bien qu&#039;il ne soit plus utilisé par ce routage.&lt;br /&gt;
&lt;br /&gt;
=== Résultats des tests ===&lt;br /&gt;
&lt;br /&gt;
Les vérifications réalisées le 20 octobre 2026 depuis une connexion extérieure au bureau ont donné :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Test&lt;br /&gt;
! Résultat&lt;br /&gt;
|-&lt;br /&gt;
| https://ad64-matomo.pleade.com/matomo.js&lt;br /&gt;
| HTTP 200&lt;br /&gt;
|-&lt;br /&gt;
| https://ad64-matomo.pleade.com/matomo.php&lt;br /&gt;
| HTTP 200&lt;br /&gt;
|-&lt;br /&gt;
| https://ad64-matomo.pleade.com/&lt;br /&gt;
| HTTP 403&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les visites Drupal Internet et Salle de lecture avaient également été enregistrées dans MariaDB, avec les identifiants Matomo 2 et 3.&lt;br /&gt;
&lt;br /&gt;
La collecte et la restriction d&#039;accès ont donc été vérifiées.&lt;br /&gt;
&lt;br /&gt;
== 11. Points de vigilance ==&lt;br /&gt;
&lt;br /&gt;
* Ne jamais ouvrir toute l&#039;interface Matomo à Internet uniquement pour permettre la collecte.&lt;br /&gt;
* Ne pas autoriser systématiquement les adresses IP du client à accéder à l&#039;administration.&lt;br /&gt;
* Ne pas bloquer les points de collecte nécessaires aux visiteurs.&lt;br /&gt;
* Ne pas modifier directement les fichiers HAProxy générés par Ansible.&lt;br /&gt;
* Tester depuis une véritable connexion extérieure.&lt;br /&gt;
* Vérifier le certificat HTTPS et son renouvellement.&lt;br /&gt;
* Vérifier que la collecte réelle fonctionne, au-delà du simple chargement du JavaScript.&lt;br /&gt;
&lt;br /&gt;
== 12. Maintenance et diagnostic ==&lt;br /&gt;
&lt;br /&gt;
En cas d&#039;anomalie, vérifier successivement :&lt;br /&gt;
&lt;br /&gt;
# La résolution DNS du domaine Matomo.&lt;br /&gt;
# Le certificat HTTPS présenté par HAProxy.&lt;br /&gt;
# La correspondance de l&#039;ACL `host`.&lt;br /&gt;
# Les règles `http-request deny`.&lt;br /&gt;
# Les chemins autorisés pour le suivi.&lt;br /&gt;
# L&#039;état du backend HAProxy.&lt;br /&gt;
# La disponibilité d&#039;Apache et PHP-FPM sur la VM.&lt;br /&gt;
# La réception effective des visites dans Matomo.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Debug]] et [[Matomo/Maintenance]].&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=Matomo/HAProxy&amp;diff=6511</id>
		<title>Matomo/HAProxy</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=Matomo/HAProxy&amp;diff=6511"/>
		<updated>2026-10-20T10:43:11Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : /* 7. Déploiement avec Ansible */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Publication et sécurisation de Matomo avec HAProxy =&lt;br /&gt;
&lt;br /&gt;
== Objectif ==&lt;br /&gt;
&lt;br /&gt;
Cette procédure décrit la publication d&#039;une instance Matomo derrière les répartiteurs HAProxy d&#039;AJLSM.&lt;br /&gt;
&lt;br /&gt;
Elle permet de :&lt;br /&gt;
&lt;br /&gt;
* Publier Matomo en HTTPS.&lt;br /&gt;
* Autoriser les requêtes de collecte des statistiques provenant des visiteurs.&lt;br /&gt;
* Réserver l&#039;interface d&#039;administration aux adresses IP autorisées.&lt;br /&gt;
* Déployer une configuration identique sur les deux HAProxy à l&#039;aide d&#039;Ansible.&lt;br /&gt;
* Vérifier le fonctionnement depuis une connexion extérieure.&lt;br /&gt;
&lt;br /&gt;
Cette procédure complète :&lt;br /&gt;
&lt;br /&gt;
* [[Matomo/Installation]]&lt;br /&gt;
* [[Matomo/Apache]]&lt;br /&gt;
* [[Matomo/Drupal]]&lt;br /&gt;
* [[Matomo/Debug]]&lt;br /&gt;
&lt;br /&gt;
== 1. Architecture ==&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;infrastructure AJLSM, le trafic suit généralement le chemin suivant :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Navigateur du visiteur&lt;br /&gt;
        |&lt;br /&gt;
        | HTTPS&lt;br /&gt;
        v&lt;br /&gt;
HAProxy (haproxy-01 / haproxy-02)&lt;br /&gt;
        |&lt;br /&gt;
        | HTTPS ou HTTP interne&lt;br /&gt;
        v&lt;br /&gt;
VM applicative&lt;br /&gt;
        |&lt;br /&gt;
        v&lt;br /&gt;
Apache + PHP-FPM + Matomo&lt;br /&gt;
        |&lt;br /&gt;
        v&lt;br /&gt;
MariaDB&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le navigateur charge le JavaScript Matomo et transmet les données de fréquentation au serveur Matomo.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; la collecte des statistiques doit fonctionner pour les visiteurs extérieurs, même lorsque l&#039;interface d&#039;administration Matomo est réservée à AJLSM.&lt;br /&gt;
&lt;br /&gt;
== 2. Prérequis ==&lt;br /&gt;
&lt;br /&gt;
Avant de modifier HAProxy, vérifier :&lt;br /&gt;
&lt;br /&gt;
* Que Matomo fonctionne sur la VM applicative.&lt;br /&gt;
* Que le VirtualHost Apache est configuré.&lt;br /&gt;
* Que le nom DNS public de Matomo est défini.&lt;br /&gt;
* Que le certificat HTTPS public est disponible sur HAProxy.&lt;br /&gt;
* Que le backend Matomo est joignable depuis les répartiteurs.&lt;br /&gt;
* Que l&#039;adresse IP ou le réseau autorisé pour l&#039;administration est connu.&lt;br /&gt;
&lt;br /&gt;
La configuration HAProxy est gérée par Ansible. Les modifications doivent être réalisées dans les fichiers sources du dépôt `ansible-ajlsm`, et non directement dans `/etc/haproxy/haproxy.cfg` sur les serveurs.&lt;br /&gt;
&lt;br /&gt;
== 3. Paramètres à personnaliser ==&lt;br /&gt;
&lt;br /&gt;
Pour chaque nouvelle installation, identifier les paramètres suivants :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Paramètre&lt;br /&gt;
! Exemple&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| Domaine Matomo&lt;br /&gt;
| matomo.exemple.fr&lt;br /&gt;
| Nom DNS public de Matomo&lt;br /&gt;
|-&lt;br /&gt;
| Backend&lt;br /&gt;
| back_ssl_projet_matomo&lt;br /&gt;
| Nom du backend HAProxy&lt;br /&gt;
|-&lt;br /&gt;
| Adresse de la VM&lt;br /&gt;
| 10.0.0.X&lt;br /&gt;
| Adresse privée de la VM hébergeant Matomo&lt;br /&gt;
|-&lt;br /&gt;
| Port backend&lt;br /&gt;
| 443&lt;br /&gt;
| Port HTTPS interne, si utilisé&lt;br /&gt;
|-&lt;br /&gt;
| ACL des administrateurs&lt;br /&gt;
| allowed_ajlsm&lt;br /&gt;
| Adresses IP autorisées à accéder à l&#039;interface&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 4. Configuration des ACL ==&lt;br /&gt;
&lt;br /&gt;
=== Principe ===&lt;br /&gt;
&lt;br /&gt;
Deux chemins sont nécessaires au suivi Matomo standard :&lt;br /&gt;
&lt;br /&gt;
* `/matomo.js` : chargement du JavaScript de suivi.&lt;br /&gt;
* `/matomo.php` : réception des données de fréquentation.&lt;br /&gt;
&lt;br /&gt;
Ces deux chemins doivent rester accessibles publiquement.&lt;br /&gt;
&lt;br /&gt;
Les autres chemins de l&#039;interface Matomo sont réservés aux adresses IP autorisées.&lt;br /&gt;
&lt;br /&gt;
=== Exemple générique ===&lt;br /&gt;
&lt;br /&gt;
Ajouter les règles suivantes dans le frontend HAProxy approprié :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;haproxy&amp;quot;&amp;gt;&lt;br /&gt;
# MATOMO - PROJET&lt;br /&gt;
acl host_projet_matomo hdr(host),host_only -i matomo.exemple.fr&lt;br /&gt;
&lt;br /&gt;
# Ressources de collecte accessibles publiquement&lt;br /&gt;
acl projet_matomo_tracking path -i /matomo.js /matomo.php&lt;br /&gt;
&lt;br /&gt;
# Interface Matomo réservée à AJLSM&lt;br /&gt;
http-request deny if host_projet_matomo !allowed_ajlsm !projet_matomo_tracking&lt;br /&gt;
&lt;br /&gt;
# Redirection HTTP vers HTTPS&lt;br /&gt;
http-request redirect scheme https if host_projet_matomo !{ ssl_fc }&lt;br /&gt;
&lt;br /&gt;
# Routage vers le backend Matomo&lt;br /&gt;
use_backend back_ssl_projet_matomo if host_projet_matomo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; cet exemple utilise l&#039;ACL `allowed_ajlsm` déjà présente dans l&#039;infrastructure AJLSM. Vérifier son existence et son contenu avant de déployer la configuration.&lt;br /&gt;
&lt;br /&gt;
L&#039;ACL `path -i` effectue une correspondance exacte des chemins. Elle ne rend pas accessibles les autres pages de l&#039;administration Matomo.&lt;br /&gt;
&lt;br /&gt;
Cette configuration est adaptée au suivi JavaScript standard. Si des fonctionnalités supplémentaires nécessitent d&#039;autres points d&#039;accès, leurs chemins doivent être étudiés séparément avant toute ouverture.&lt;br /&gt;
&lt;br /&gt;
== 5. Configuration du backend ==&lt;br /&gt;
&lt;br /&gt;
=== Exemple HTTPS ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
backend back_ssl_projet_matomo&lt;br /&gt;
    server SSLPROJETMATOMO 10.0.0.X:443 check ssl verify none sni str(matomo.exemple.fr)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remplacer l&#039;adresse IP, le nom du serveur et le nom de domaine par les paramètres du projet.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Sécurité :&#039;&#039;&#039; `verify none` désactive la vérification du certificat présenté par le backend. Cette configuration existe sur AD64, mais ne doit pas être considérée comme une recommandation générale.&lt;br /&gt;
&lt;br /&gt;
Pour une nouvelle installation, privilégier une validation TLS du backend avec une autorité de certification appropriée lorsque l&#039;architecture le permet.&lt;br /&gt;
&lt;br /&gt;
=== Backend HTTP ===&lt;br /&gt;
&lt;br /&gt;
Un backend HTTP peut également être utilisé sur un réseau interne maîtrisé :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
backend back_projet_matomo&lt;br /&gt;
    server PROJETMATOMO 10.0.0.X:80 check&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le choix entre HTTP et HTTPS interne dépend de l&#039;architecture du projet et des exigences de sécurité.&lt;br /&gt;
&lt;br /&gt;
== 6. Certificats HTTPS ==&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;infrastructure AJLSM, les certificats publics HAProxy peuvent être gérés par `acme.sh`.&lt;br /&gt;
&lt;br /&gt;
Sur les serveurs HAProxy concernés, vérifier :&lt;br /&gt;
&lt;br /&gt;
* L&#039;existence du certificat pour le domaine Matomo.&lt;br /&gt;
* Sa date d&#039;expiration.&lt;br /&gt;
* La configuration de renouvellement automatique.&lt;br /&gt;
* Le mécanisme de déploiement du certificat dans HAProxy.&lt;br /&gt;
&lt;br /&gt;
Exemple de vérification depuis un poste client :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
openssl s_client \&lt;br /&gt;
  -connect matomo.exemple.fr:443 \&lt;br /&gt;
  -servername matomo.exemple.fr &amp;lt;/dev/null 2&amp;gt;/dev/null \&lt;br /&gt;
  | openssl x509 -noout -subject -issuer -dates&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La présence d&#039;une tâche automatique de renouvellement ne garantit pas à elle seule que le déploiement d&#039;un nouveau certificat fonctionnera. Le renouvellement et le rechargement effectif du certificat doivent être contrôlés.&lt;br /&gt;
&lt;br /&gt;
== 7. Déploiement avec Ansible ==&lt;br /&gt;
Voir aussi :[[WAF_2026#Ansible]]&lt;br /&gt;
=== Modification ===&lt;br /&gt;
&lt;br /&gt;
Depuis le Mac d&#039;administration :&lt;br /&gt;
&lt;br /&gt;
# Ouvrir le dépôt `ansible-ajlsm`.&lt;br /&gt;
# Modifier la configuration HAProxy dans les sources Ansible.&lt;br /&gt;
# Ajouter les ACL et le routage du nouveau domaine Matomo.&lt;br /&gt;
# Vérifier que les backends sont définis.&lt;br /&gt;
# Ne pas modifier directement les configurations générées sur les deux serveurs.&lt;br /&gt;
&lt;br /&gt;
=== Vérification de la syntaxe du playbook ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer --syntax-check&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Simulation du déploiement ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer --check --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier :&lt;br /&gt;
&lt;br /&gt;
* Que les modifications sont identiques sur les deux HAProxy.&lt;br /&gt;
* Que seuls les blocs attendus changent.&lt;br /&gt;
* Qu&#039;aucune configuration d&#039;un autre client n&#039;est modifiée.&lt;br /&gt;
* Qu&#039;aucune erreur n&#039;est signalée.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; le mode `--check` est une simulation. Il ne garantit pas à lui seul le succès du déploiement réel ni le comportement des ACL en production.&lt;br /&gt;
&lt;br /&gt;
=== Déploiement réel ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier le résultat du playbook sur les deux serveurs.&lt;br /&gt;
&lt;br /&gt;
Si le playbook prévoit un redémarrage ou un rechargement HAProxy, contrôler ensuite que les services restent actifs et que les applications existantes répondent normalement.&lt;br /&gt;
&lt;br /&gt;
== 8. Vérification depuis une connexion extérieure ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; effectuer les tests depuis une connexion qui n&#039;utilise ni l&#039;adresse IP publique du bureau ni le VPN AJLSM.&lt;br /&gt;
&lt;br /&gt;
Une connexion autorisée ne permet pas de vérifier correctement le refus d&#039;accès à l&#039;administration.&lt;br /&gt;
&lt;br /&gt;
=== Tester les ressources de suivi ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
MATOMO_URL=&amp;quot;https://matomo.exemple.fr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
for RESOURCE in matomo.js matomo.php; do&lt;br /&gt;
    echo &amp;quot;===== /$RESOURCE =====&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    curl -sS -o /dev/null -w &amp;quot;HTTP %{http_code}\n&amp;quot; \&lt;br /&gt;
        &amp;quot;$MATOMO_URL/$RESOURCE&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultats attendus pour l&#039;installation standard :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Ressource&lt;br /&gt;
! Résultat attendu&lt;br /&gt;
|-&lt;br /&gt;
| /matomo.js&lt;br /&gt;
| HTTP 200&lt;br /&gt;
|-&lt;br /&gt;
| /matomo.php&lt;br /&gt;
| Accessible sans HTTP 403 HAProxy&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Remarque :&#039;&#039;&#039; une réponse HTTP 200 de `matomo.php` sans paramètres de suivi ne constitue pas une preuve de collecte effective.&lt;br /&gt;
&lt;br /&gt;
=== Tester la protection de l&#039;administration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -sS -o /dev/null -w &amp;quot;HTTP %{http_code}\n&amp;quot; \&lt;br /&gt;
    &amp;quot;$MATOMO_URL/&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat attendu depuis une adresse IP extérieure non autorisée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
HTTP 403&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tester depuis une adresse autorisée ===&lt;br /&gt;
&lt;br /&gt;
Depuis le réseau AJLSM ou un accès VPN autorisé, vérifier que l&#039;interface Matomo reste accessible et que l&#039;authentification Matomo fonctionne.&lt;br /&gt;
&lt;br /&gt;
== 9. Vérification de la collecte ==&lt;br /&gt;
&lt;br /&gt;
Une fois les règles HAProxy appliquées :&lt;br /&gt;
&lt;br /&gt;
# Ouvrir une application Drupal ou Pleade suivie par Matomo.&lt;br /&gt;
# Naviguer sur plusieurs pages publiques.&lt;br /&gt;
# Vérifier l&#039;envoi des requêtes de suivi dans les outils réseau du navigateur.&lt;br /&gt;
# Vérifier l&#039;apparition des visites dans l&#039;interface Matomo.&lt;br /&gt;
&lt;br /&gt;
Pour une vérification directe en base :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT&lt;br /&gt;
    idsite,&lt;br /&gt;
    COUNT(*) AS visites,&lt;br /&gt;
    MAX(visit_last_action_time) AS derniere_activite&lt;br /&gt;
FROM matomo_log_visit&lt;br /&gt;
GROUP BY idsite;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette requête doit être exécutée dans la base Matomo avec un compte disposant des droits nécessaires.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Drupal]] et [[Matomo/Debug]].&lt;br /&gt;
&lt;br /&gt;
== 10. Exemple validé : AD64 — octobre 2026 ==&lt;br /&gt;
&lt;br /&gt;
=== Environnement ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Élément&lt;br /&gt;
! Valeur&lt;br /&gt;
|-&lt;br /&gt;
| Serveur Matomo&lt;br /&gt;
| ad64&lt;br /&gt;
|-&lt;br /&gt;
| Domaine&lt;br /&gt;
| ad64-matomo.pleade.com&lt;br /&gt;
|-&lt;br /&gt;
| Adresse privée de la VM&lt;br /&gt;
| 10.0.0.41&lt;br /&gt;
|-&lt;br /&gt;
| Backend HTTPS&lt;br /&gt;
| back_ssl_ad64_matomo&lt;br /&gt;
|-&lt;br /&gt;
| Répartiteurs&lt;br /&gt;
| haproxy-01 et haproxy-02&lt;br /&gt;
|-&lt;br /&gt;
| Applications suivies&lt;br /&gt;
| Drupal Internet et Drupal Salle de lecture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Configuration HAProxy ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
# AD64 MATOMO&lt;br /&gt;
acl host_ad64_matomo hdr(host),host_only -i ad64-matomo.pleade.com&lt;br /&gt;
&lt;br /&gt;
# Points de collecte accessibles publiquement&lt;br /&gt;
acl ad64_matomo_tracking path -i /matomo.js /matomo.php&lt;br /&gt;
&lt;br /&gt;
# Administration réservée à AJLSM&lt;br /&gt;
http-request deny if host_ad64_matomo !allowed_ajlsm !ad64_matomo_tracking&lt;br /&gt;
&lt;br /&gt;
http-request redirect scheme https if host_ad64_matomo !{ ssl_fc }&lt;br /&gt;
&lt;br /&gt;
use_backend back_ssl_ad64_matomo if host_ad64_matomo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Backend HTTPS existant :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
backend back_ssl_ad64_matomo&lt;br /&gt;
    server SSLAD64MATOMO 10.0.0.41:443 check ssl verify none sni str(ad64-matomo.pleade.com)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;ancien backend HTTP `back_ad64_matomo` a été conservé sans modification, bien qu&#039;il ne soit plus utilisé par ce routage.&lt;br /&gt;
&lt;br /&gt;
=== Résultats des tests ===&lt;br /&gt;
&lt;br /&gt;
Les vérifications réalisées le 20 octobre 2026 depuis une connexion extérieure au bureau ont donné :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Test&lt;br /&gt;
! Résultat&lt;br /&gt;
|-&lt;br /&gt;
| https://ad64-matomo.pleade.com/matomo.js&lt;br /&gt;
| HTTP 200&lt;br /&gt;
|-&lt;br /&gt;
| https://ad64-matomo.pleade.com/matomo.php&lt;br /&gt;
| HTTP 200&lt;br /&gt;
|-&lt;br /&gt;
| https://ad64-matomo.pleade.com/&lt;br /&gt;
| HTTP 403&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les visites Drupal Internet et Salle de lecture avaient également été enregistrées dans MariaDB, avec les identifiants Matomo 2 et 3.&lt;br /&gt;
&lt;br /&gt;
La collecte et la restriction d&#039;accès ont donc été vérifiées.&lt;br /&gt;
&lt;br /&gt;
== 11. Points de vigilance ==&lt;br /&gt;
&lt;br /&gt;
* Ne jamais ouvrir toute l&#039;interface Matomo à Internet uniquement pour permettre la collecte.&lt;br /&gt;
* Ne pas autoriser systématiquement les adresses IP du client à accéder à l&#039;administration.&lt;br /&gt;
* Ne pas bloquer les points de collecte nécessaires aux visiteurs.&lt;br /&gt;
* Ne pas modifier directement les fichiers HAProxy générés par Ansible.&lt;br /&gt;
* Tester depuis une véritable connexion extérieure.&lt;br /&gt;
* Vérifier le certificat HTTPS et son renouvellement.&lt;br /&gt;
* Vérifier que la collecte réelle fonctionne, au-delà du simple chargement du JavaScript.&lt;br /&gt;
&lt;br /&gt;
== 12. Maintenance et diagnostic ==&lt;br /&gt;
&lt;br /&gt;
En cas d&#039;anomalie, vérifier successivement :&lt;br /&gt;
&lt;br /&gt;
# La résolution DNS du domaine Matomo.&lt;br /&gt;
# Le certificat HTTPS présenté par HAProxy.&lt;br /&gt;
# La correspondance de l&#039;ACL `host`.&lt;br /&gt;
# Les règles `http-request deny`.&lt;br /&gt;
# Les chemins autorisés pour le suivi.&lt;br /&gt;
# L&#039;état du backend HAProxy.&lt;br /&gt;
# La disponibilité d&#039;Apache et PHP-FPM sur la VM.&lt;br /&gt;
# La réception effective des visites dans Matomo.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Debug]] et [[Matomo/Maintenance]].&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=Matomo/HAProxy&amp;diff=6510</id>
		<title>Matomo/HAProxy</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=Matomo/HAProxy&amp;diff=6510"/>
		<updated>2026-10-20T10:41:42Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : /* Configuration HAProxy */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Publication et sécurisation de Matomo avec HAProxy =&lt;br /&gt;
&lt;br /&gt;
== Objectif ==&lt;br /&gt;
&lt;br /&gt;
Cette procédure décrit la publication d&#039;une instance Matomo derrière les répartiteurs HAProxy d&#039;AJLSM.&lt;br /&gt;
&lt;br /&gt;
Elle permet de :&lt;br /&gt;
&lt;br /&gt;
* Publier Matomo en HTTPS.&lt;br /&gt;
* Autoriser les requêtes de collecte des statistiques provenant des visiteurs.&lt;br /&gt;
* Réserver l&#039;interface d&#039;administration aux adresses IP autorisées.&lt;br /&gt;
* Déployer une configuration identique sur les deux HAProxy à l&#039;aide d&#039;Ansible.&lt;br /&gt;
* Vérifier le fonctionnement depuis une connexion extérieure.&lt;br /&gt;
&lt;br /&gt;
Cette procédure complète :&lt;br /&gt;
&lt;br /&gt;
* [[Matomo/Installation]]&lt;br /&gt;
* [[Matomo/Apache]]&lt;br /&gt;
* [[Matomo/Drupal]]&lt;br /&gt;
* [[Matomo/Debug]]&lt;br /&gt;
&lt;br /&gt;
== 1. Architecture ==&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;infrastructure AJLSM, le trafic suit généralement le chemin suivant :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Navigateur du visiteur&lt;br /&gt;
        |&lt;br /&gt;
        | HTTPS&lt;br /&gt;
        v&lt;br /&gt;
HAProxy (haproxy-01 / haproxy-02)&lt;br /&gt;
        |&lt;br /&gt;
        | HTTPS ou HTTP interne&lt;br /&gt;
        v&lt;br /&gt;
VM applicative&lt;br /&gt;
        |&lt;br /&gt;
        v&lt;br /&gt;
Apache + PHP-FPM + Matomo&lt;br /&gt;
        |&lt;br /&gt;
        v&lt;br /&gt;
MariaDB&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le navigateur charge le JavaScript Matomo et transmet les données de fréquentation au serveur Matomo.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; la collecte des statistiques doit fonctionner pour les visiteurs extérieurs, même lorsque l&#039;interface d&#039;administration Matomo est réservée à AJLSM.&lt;br /&gt;
&lt;br /&gt;
== 2. Prérequis ==&lt;br /&gt;
&lt;br /&gt;
Avant de modifier HAProxy, vérifier :&lt;br /&gt;
&lt;br /&gt;
* Que Matomo fonctionne sur la VM applicative.&lt;br /&gt;
* Que le VirtualHost Apache est configuré.&lt;br /&gt;
* Que le nom DNS public de Matomo est défini.&lt;br /&gt;
* Que le certificat HTTPS public est disponible sur HAProxy.&lt;br /&gt;
* Que le backend Matomo est joignable depuis les répartiteurs.&lt;br /&gt;
* Que l&#039;adresse IP ou le réseau autorisé pour l&#039;administration est connu.&lt;br /&gt;
&lt;br /&gt;
La configuration HAProxy est gérée par Ansible. Les modifications doivent être réalisées dans les fichiers sources du dépôt `ansible-ajlsm`, et non directement dans `/etc/haproxy/haproxy.cfg` sur les serveurs.&lt;br /&gt;
&lt;br /&gt;
== 3. Paramètres à personnaliser ==&lt;br /&gt;
&lt;br /&gt;
Pour chaque nouvelle installation, identifier les paramètres suivants :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Paramètre&lt;br /&gt;
! Exemple&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| Domaine Matomo&lt;br /&gt;
| matomo.exemple.fr&lt;br /&gt;
| Nom DNS public de Matomo&lt;br /&gt;
|-&lt;br /&gt;
| Backend&lt;br /&gt;
| back_ssl_projet_matomo&lt;br /&gt;
| Nom du backend HAProxy&lt;br /&gt;
|-&lt;br /&gt;
| Adresse de la VM&lt;br /&gt;
| 10.0.0.X&lt;br /&gt;
| Adresse privée de la VM hébergeant Matomo&lt;br /&gt;
|-&lt;br /&gt;
| Port backend&lt;br /&gt;
| 443&lt;br /&gt;
| Port HTTPS interne, si utilisé&lt;br /&gt;
|-&lt;br /&gt;
| ACL des administrateurs&lt;br /&gt;
| allowed_ajlsm&lt;br /&gt;
| Adresses IP autorisées à accéder à l&#039;interface&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 4. Configuration des ACL ==&lt;br /&gt;
&lt;br /&gt;
=== Principe ===&lt;br /&gt;
&lt;br /&gt;
Deux chemins sont nécessaires au suivi Matomo standard :&lt;br /&gt;
&lt;br /&gt;
* `/matomo.js` : chargement du JavaScript de suivi.&lt;br /&gt;
* `/matomo.php` : réception des données de fréquentation.&lt;br /&gt;
&lt;br /&gt;
Ces deux chemins doivent rester accessibles publiquement.&lt;br /&gt;
&lt;br /&gt;
Les autres chemins de l&#039;interface Matomo sont réservés aux adresses IP autorisées.&lt;br /&gt;
&lt;br /&gt;
=== Exemple générique ===&lt;br /&gt;
&lt;br /&gt;
Ajouter les règles suivantes dans le frontend HAProxy approprié :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;haproxy&amp;quot;&amp;gt;&lt;br /&gt;
# MATOMO - PROJET&lt;br /&gt;
acl host_projet_matomo hdr(host),host_only -i matomo.exemple.fr&lt;br /&gt;
&lt;br /&gt;
# Ressources de collecte accessibles publiquement&lt;br /&gt;
acl projet_matomo_tracking path -i /matomo.js /matomo.php&lt;br /&gt;
&lt;br /&gt;
# Interface Matomo réservée à AJLSM&lt;br /&gt;
http-request deny if host_projet_matomo !allowed_ajlsm !projet_matomo_tracking&lt;br /&gt;
&lt;br /&gt;
# Redirection HTTP vers HTTPS&lt;br /&gt;
http-request redirect scheme https if host_projet_matomo !{ ssl_fc }&lt;br /&gt;
&lt;br /&gt;
# Routage vers le backend Matomo&lt;br /&gt;
use_backend back_ssl_projet_matomo if host_projet_matomo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; cet exemple utilise l&#039;ACL `allowed_ajlsm` déjà présente dans l&#039;infrastructure AJLSM. Vérifier son existence et son contenu avant de déployer la configuration.&lt;br /&gt;
&lt;br /&gt;
L&#039;ACL `path -i` effectue une correspondance exacte des chemins. Elle ne rend pas accessibles les autres pages de l&#039;administration Matomo.&lt;br /&gt;
&lt;br /&gt;
Cette configuration est adaptée au suivi JavaScript standard. Si des fonctionnalités supplémentaires nécessitent d&#039;autres points d&#039;accès, leurs chemins doivent être étudiés séparément avant toute ouverture.&lt;br /&gt;
&lt;br /&gt;
== 5. Configuration du backend ==&lt;br /&gt;
&lt;br /&gt;
=== Exemple HTTPS ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
backend back_ssl_projet_matomo&lt;br /&gt;
    server SSLPROJETMATOMO 10.0.0.X:443 check ssl verify none sni str(matomo.exemple.fr)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remplacer l&#039;adresse IP, le nom du serveur et le nom de domaine par les paramètres du projet.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Sécurité :&#039;&#039;&#039; `verify none` désactive la vérification du certificat présenté par le backend. Cette configuration existe sur AD64, mais ne doit pas être considérée comme une recommandation générale.&lt;br /&gt;
&lt;br /&gt;
Pour une nouvelle installation, privilégier une validation TLS du backend avec une autorité de certification appropriée lorsque l&#039;architecture le permet.&lt;br /&gt;
&lt;br /&gt;
=== Backend HTTP ===&lt;br /&gt;
&lt;br /&gt;
Un backend HTTP peut également être utilisé sur un réseau interne maîtrisé :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
backend back_projet_matomo&lt;br /&gt;
    server PROJETMATOMO 10.0.0.X:80 check&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le choix entre HTTP et HTTPS interne dépend de l&#039;architecture du projet et des exigences de sécurité.&lt;br /&gt;
&lt;br /&gt;
== 6. Certificats HTTPS ==&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;infrastructure AJLSM, les certificats publics HAProxy peuvent être gérés par `acme.sh`.&lt;br /&gt;
&lt;br /&gt;
Sur les serveurs HAProxy concernés, vérifier :&lt;br /&gt;
&lt;br /&gt;
* L&#039;existence du certificat pour le domaine Matomo.&lt;br /&gt;
* Sa date d&#039;expiration.&lt;br /&gt;
* La configuration de renouvellement automatique.&lt;br /&gt;
* Le mécanisme de déploiement du certificat dans HAProxy.&lt;br /&gt;
&lt;br /&gt;
Exemple de vérification depuis un poste client :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
openssl s_client \&lt;br /&gt;
  -connect matomo.exemple.fr:443 \&lt;br /&gt;
  -servername matomo.exemple.fr &amp;lt;/dev/null 2&amp;gt;/dev/null \&lt;br /&gt;
  | openssl x509 -noout -subject -issuer -dates&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La présence d&#039;une tâche automatique de renouvellement ne garantit pas à elle seule que le déploiement d&#039;un nouveau certificat fonctionnera. Le renouvellement et le rechargement effectif du certificat doivent être contrôlés.&lt;br /&gt;
&lt;br /&gt;
== 7. Déploiement avec Ansible ==&lt;br /&gt;
&lt;br /&gt;
=== Modification ===&lt;br /&gt;
&lt;br /&gt;
Depuis le Mac d&#039;administration :&lt;br /&gt;
&lt;br /&gt;
# Ouvrir le dépôt `ansible-ajlsm`.&lt;br /&gt;
# Modifier la configuration HAProxy dans les sources Ansible.&lt;br /&gt;
# Ajouter les ACL et le routage du nouveau domaine Matomo.&lt;br /&gt;
# Vérifier que les backends sont définis.&lt;br /&gt;
# Ne pas modifier directement les configurations générées sur les deux serveurs.&lt;br /&gt;
&lt;br /&gt;
=== Vérification de la syntaxe du playbook ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer --syntax-check&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Simulation du déploiement ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer --check --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier :&lt;br /&gt;
&lt;br /&gt;
* Que les modifications sont identiques sur les deux HAProxy.&lt;br /&gt;
* Que seuls les blocs attendus changent.&lt;br /&gt;
* Qu&#039;aucune configuration d&#039;un autre client n&#039;est modifiée.&lt;br /&gt;
* Qu&#039;aucune erreur n&#039;est signalée.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; le mode `--check` est une simulation. Il ne garantit pas à lui seul le succès du déploiement réel ni le comportement des ACL en production.&lt;br /&gt;
&lt;br /&gt;
=== Déploiement réel ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier le résultat du playbook sur les deux serveurs.&lt;br /&gt;
&lt;br /&gt;
Si le playbook prévoit un redémarrage ou un rechargement HAProxy, contrôler ensuite que les services restent actifs et que les applications existantes répondent normalement.&lt;br /&gt;
&lt;br /&gt;
== 8. Vérification depuis une connexion extérieure ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; effectuer les tests depuis une connexion qui n&#039;utilise ni l&#039;adresse IP publique du bureau ni le VPN AJLSM.&lt;br /&gt;
&lt;br /&gt;
Une connexion autorisée ne permet pas de vérifier correctement le refus d&#039;accès à l&#039;administration.&lt;br /&gt;
&lt;br /&gt;
=== Tester les ressources de suivi ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
MATOMO_URL=&amp;quot;https://matomo.exemple.fr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
for RESOURCE in matomo.js matomo.php; do&lt;br /&gt;
    echo &amp;quot;===== /$RESOURCE =====&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    curl -sS -o /dev/null -w &amp;quot;HTTP %{http_code}\n&amp;quot; \&lt;br /&gt;
        &amp;quot;$MATOMO_URL/$RESOURCE&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultats attendus pour l&#039;installation standard :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Ressource&lt;br /&gt;
! Résultat attendu&lt;br /&gt;
|-&lt;br /&gt;
| /matomo.js&lt;br /&gt;
| HTTP 200&lt;br /&gt;
|-&lt;br /&gt;
| /matomo.php&lt;br /&gt;
| Accessible sans HTTP 403 HAProxy&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Remarque :&#039;&#039;&#039; une réponse HTTP 200 de `matomo.php` sans paramètres de suivi ne constitue pas une preuve de collecte effective.&lt;br /&gt;
&lt;br /&gt;
=== Tester la protection de l&#039;administration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -sS -o /dev/null -w &amp;quot;HTTP %{http_code}\n&amp;quot; \&lt;br /&gt;
    &amp;quot;$MATOMO_URL/&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat attendu depuis une adresse IP extérieure non autorisée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
HTTP 403&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tester depuis une adresse autorisée ===&lt;br /&gt;
&lt;br /&gt;
Depuis le réseau AJLSM ou un accès VPN autorisé, vérifier que l&#039;interface Matomo reste accessible et que l&#039;authentification Matomo fonctionne.&lt;br /&gt;
&lt;br /&gt;
== 9. Vérification de la collecte ==&lt;br /&gt;
&lt;br /&gt;
Une fois les règles HAProxy appliquées :&lt;br /&gt;
&lt;br /&gt;
# Ouvrir une application Drupal ou Pleade suivie par Matomo.&lt;br /&gt;
# Naviguer sur plusieurs pages publiques.&lt;br /&gt;
# Vérifier l&#039;envoi des requêtes de suivi dans les outils réseau du navigateur.&lt;br /&gt;
# Vérifier l&#039;apparition des visites dans l&#039;interface Matomo.&lt;br /&gt;
&lt;br /&gt;
Pour une vérification directe en base :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT&lt;br /&gt;
    idsite,&lt;br /&gt;
    COUNT(*) AS visites,&lt;br /&gt;
    MAX(visit_last_action_time) AS derniere_activite&lt;br /&gt;
FROM matomo_log_visit&lt;br /&gt;
GROUP BY idsite;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette requête doit être exécutée dans la base Matomo avec un compte disposant des droits nécessaires.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Drupal]] et [[Matomo/Debug]].&lt;br /&gt;
&lt;br /&gt;
== 10. Exemple validé : AD64 — octobre 2026 ==&lt;br /&gt;
&lt;br /&gt;
=== Environnement ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Élément&lt;br /&gt;
! Valeur&lt;br /&gt;
|-&lt;br /&gt;
| Serveur Matomo&lt;br /&gt;
| ad64&lt;br /&gt;
|-&lt;br /&gt;
| Domaine&lt;br /&gt;
| ad64-matomo.pleade.com&lt;br /&gt;
|-&lt;br /&gt;
| Adresse privée de la VM&lt;br /&gt;
| 10.0.0.41&lt;br /&gt;
|-&lt;br /&gt;
| Backend HTTPS&lt;br /&gt;
| back_ssl_ad64_matomo&lt;br /&gt;
|-&lt;br /&gt;
| Répartiteurs&lt;br /&gt;
| haproxy-01 et haproxy-02&lt;br /&gt;
|-&lt;br /&gt;
| Applications suivies&lt;br /&gt;
| Drupal Internet et Drupal Salle de lecture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Configuration HAProxy ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
# AD64 MATOMO&lt;br /&gt;
acl host_ad64_matomo hdr(host),host_only -i ad64-matomo.pleade.com&lt;br /&gt;
&lt;br /&gt;
# Points de collecte accessibles publiquement&lt;br /&gt;
acl ad64_matomo_tracking path -i /matomo.js /matomo.php&lt;br /&gt;
&lt;br /&gt;
# Administration réservée à AJLSM&lt;br /&gt;
http-request deny if host_ad64_matomo !allowed_ajlsm !ad64_matomo_tracking&lt;br /&gt;
&lt;br /&gt;
http-request redirect scheme https if host_ad64_matomo !{ ssl_fc }&lt;br /&gt;
&lt;br /&gt;
use_backend back_ssl_ad64_matomo if host_ad64_matomo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Backend HTTPS existant :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
backend back_ssl_ad64_matomo&lt;br /&gt;
    server SSLAD64MATOMO 10.0.0.41:443 check ssl verify none sni str(ad64-matomo.pleade.com)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;ancien backend HTTP `back_ad64_matomo` a été conservé sans modification, bien qu&#039;il ne soit plus utilisé par ce routage.&lt;br /&gt;
&lt;br /&gt;
=== Résultats des tests ===&lt;br /&gt;
&lt;br /&gt;
Les vérifications réalisées le 20 octobre 2026 depuis une connexion extérieure au bureau ont donné :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Test&lt;br /&gt;
! Résultat&lt;br /&gt;
|-&lt;br /&gt;
| https://ad64-matomo.pleade.com/matomo.js&lt;br /&gt;
| HTTP 200&lt;br /&gt;
|-&lt;br /&gt;
| https://ad64-matomo.pleade.com/matomo.php&lt;br /&gt;
| HTTP 200&lt;br /&gt;
|-&lt;br /&gt;
| https://ad64-matomo.pleade.com/&lt;br /&gt;
| HTTP 403&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les visites Drupal Internet et Salle de lecture avaient également été enregistrées dans MariaDB, avec les identifiants Matomo 2 et 3.&lt;br /&gt;
&lt;br /&gt;
La collecte et la restriction d&#039;accès ont donc été vérifiées.&lt;br /&gt;
&lt;br /&gt;
== 11. Points de vigilance ==&lt;br /&gt;
&lt;br /&gt;
* Ne jamais ouvrir toute l&#039;interface Matomo à Internet uniquement pour permettre la collecte.&lt;br /&gt;
* Ne pas autoriser systématiquement les adresses IP du client à accéder à l&#039;administration.&lt;br /&gt;
* Ne pas bloquer les points de collecte nécessaires aux visiteurs.&lt;br /&gt;
* Ne pas modifier directement les fichiers HAProxy générés par Ansible.&lt;br /&gt;
* Tester depuis une véritable connexion extérieure.&lt;br /&gt;
* Vérifier le certificat HTTPS et son renouvellement.&lt;br /&gt;
* Vérifier que la collecte réelle fonctionne, au-delà du simple chargement du JavaScript.&lt;br /&gt;
&lt;br /&gt;
== 12. Maintenance et diagnostic ==&lt;br /&gt;
&lt;br /&gt;
En cas d&#039;anomalie, vérifier successivement :&lt;br /&gt;
&lt;br /&gt;
# La résolution DNS du domaine Matomo.&lt;br /&gt;
# Le certificat HTTPS présenté par HAProxy.&lt;br /&gt;
# La correspondance de l&#039;ACL `host`.&lt;br /&gt;
# Les règles `http-request deny`.&lt;br /&gt;
# Les chemins autorisés pour le suivi.&lt;br /&gt;
# L&#039;état du backend HAProxy.&lt;br /&gt;
# La disponibilité d&#039;Apache et PHP-FPM sur la VM.&lt;br /&gt;
# La réception effective des visites dans Matomo.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Debug]] et [[Matomo/Maintenance]].&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=Matomo/HAProxy&amp;diff=6509</id>
		<title>Matomo/HAProxy</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=Matomo/HAProxy&amp;diff=6509"/>
		<updated>2026-10-20T10:41:25Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : /* Backend HTTP */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Publication et sécurisation de Matomo avec HAProxy =&lt;br /&gt;
&lt;br /&gt;
== Objectif ==&lt;br /&gt;
&lt;br /&gt;
Cette procédure décrit la publication d&#039;une instance Matomo derrière les répartiteurs HAProxy d&#039;AJLSM.&lt;br /&gt;
&lt;br /&gt;
Elle permet de :&lt;br /&gt;
&lt;br /&gt;
* Publier Matomo en HTTPS.&lt;br /&gt;
* Autoriser les requêtes de collecte des statistiques provenant des visiteurs.&lt;br /&gt;
* Réserver l&#039;interface d&#039;administration aux adresses IP autorisées.&lt;br /&gt;
* Déployer une configuration identique sur les deux HAProxy à l&#039;aide d&#039;Ansible.&lt;br /&gt;
* Vérifier le fonctionnement depuis une connexion extérieure.&lt;br /&gt;
&lt;br /&gt;
Cette procédure complète :&lt;br /&gt;
&lt;br /&gt;
* [[Matomo/Installation]]&lt;br /&gt;
* [[Matomo/Apache]]&lt;br /&gt;
* [[Matomo/Drupal]]&lt;br /&gt;
* [[Matomo/Debug]]&lt;br /&gt;
&lt;br /&gt;
== 1. Architecture ==&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;infrastructure AJLSM, le trafic suit généralement le chemin suivant :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Navigateur du visiteur&lt;br /&gt;
        |&lt;br /&gt;
        | HTTPS&lt;br /&gt;
        v&lt;br /&gt;
HAProxy (haproxy-01 / haproxy-02)&lt;br /&gt;
        |&lt;br /&gt;
        | HTTPS ou HTTP interne&lt;br /&gt;
        v&lt;br /&gt;
VM applicative&lt;br /&gt;
        |&lt;br /&gt;
        v&lt;br /&gt;
Apache + PHP-FPM + Matomo&lt;br /&gt;
        |&lt;br /&gt;
        v&lt;br /&gt;
MariaDB&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le navigateur charge le JavaScript Matomo et transmet les données de fréquentation au serveur Matomo.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; la collecte des statistiques doit fonctionner pour les visiteurs extérieurs, même lorsque l&#039;interface d&#039;administration Matomo est réservée à AJLSM.&lt;br /&gt;
&lt;br /&gt;
== 2. Prérequis ==&lt;br /&gt;
&lt;br /&gt;
Avant de modifier HAProxy, vérifier :&lt;br /&gt;
&lt;br /&gt;
* Que Matomo fonctionne sur la VM applicative.&lt;br /&gt;
* Que le VirtualHost Apache est configuré.&lt;br /&gt;
* Que le nom DNS public de Matomo est défini.&lt;br /&gt;
* Que le certificat HTTPS public est disponible sur HAProxy.&lt;br /&gt;
* Que le backend Matomo est joignable depuis les répartiteurs.&lt;br /&gt;
* Que l&#039;adresse IP ou le réseau autorisé pour l&#039;administration est connu.&lt;br /&gt;
&lt;br /&gt;
La configuration HAProxy est gérée par Ansible. Les modifications doivent être réalisées dans les fichiers sources du dépôt `ansible-ajlsm`, et non directement dans `/etc/haproxy/haproxy.cfg` sur les serveurs.&lt;br /&gt;
&lt;br /&gt;
== 3. Paramètres à personnaliser ==&lt;br /&gt;
&lt;br /&gt;
Pour chaque nouvelle installation, identifier les paramètres suivants :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Paramètre&lt;br /&gt;
! Exemple&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| Domaine Matomo&lt;br /&gt;
| matomo.exemple.fr&lt;br /&gt;
| Nom DNS public de Matomo&lt;br /&gt;
|-&lt;br /&gt;
| Backend&lt;br /&gt;
| back_ssl_projet_matomo&lt;br /&gt;
| Nom du backend HAProxy&lt;br /&gt;
|-&lt;br /&gt;
| Adresse de la VM&lt;br /&gt;
| 10.0.0.X&lt;br /&gt;
| Adresse privée de la VM hébergeant Matomo&lt;br /&gt;
|-&lt;br /&gt;
| Port backend&lt;br /&gt;
| 443&lt;br /&gt;
| Port HTTPS interne, si utilisé&lt;br /&gt;
|-&lt;br /&gt;
| ACL des administrateurs&lt;br /&gt;
| allowed_ajlsm&lt;br /&gt;
| Adresses IP autorisées à accéder à l&#039;interface&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 4. Configuration des ACL ==&lt;br /&gt;
&lt;br /&gt;
=== Principe ===&lt;br /&gt;
&lt;br /&gt;
Deux chemins sont nécessaires au suivi Matomo standard :&lt;br /&gt;
&lt;br /&gt;
* `/matomo.js` : chargement du JavaScript de suivi.&lt;br /&gt;
* `/matomo.php` : réception des données de fréquentation.&lt;br /&gt;
&lt;br /&gt;
Ces deux chemins doivent rester accessibles publiquement.&lt;br /&gt;
&lt;br /&gt;
Les autres chemins de l&#039;interface Matomo sont réservés aux adresses IP autorisées.&lt;br /&gt;
&lt;br /&gt;
=== Exemple générique ===&lt;br /&gt;
&lt;br /&gt;
Ajouter les règles suivantes dans le frontend HAProxy approprié :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;haproxy&amp;quot;&amp;gt;&lt;br /&gt;
# MATOMO - PROJET&lt;br /&gt;
acl host_projet_matomo hdr(host),host_only -i matomo.exemple.fr&lt;br /&gt;
&lt;br /&gt;
# Ressources de collecte accessibles publiquement&lt;br /&gt;
acl projet_matomo_tracking path -i /matomo.js /matomo.php&lt;br /&gt;
&lt;br /&gt;
# Interface Matomo réservée à AJLSM&lt;br /&gt;
http-request deny if host_projet_matomo !allowed_ajlsm !projet_matomo_tracking&lt;br /&gt;
&lt;br /&gt;
# Redirection HTTP vers HTTPS&lt;br /&gt;
http-request redirect scheme https if host_projet_matomo !{ ssl_fc }&lt;br /&gt;
&lt;br /&gt;
# Routage vers le backend Matomo&lt;br /&gt;
use_backend back_ssl_projet_matomo if host_projet_matomo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; cet exemple utilise l&#039;ACL `allowed_ajlsm` déjà présente dans l&#039;infrastructure AJLSM. Vérifier son existence et son contenu avant de déployer la configuration.&lt;br /&gt;
&lt;br /&gt;
L&#039;ACL `path -i` effectue une correspondance exacte des chemins. Elle ne rend pas accessibles les autres pages de l&#039;administration Matomo.&lt;br /&gt;
&lt;br /&gt;
Cette configuration est adaptée au suivi JavaScript standard. Si des fonctionnalités supplémentaires nécessitent d&#039;autres points d&#039;accès, leurs chemins doivent être étudiés séparément avant toute ouverture.&lt;br /&gt;
&lt;br /&gt;
== 5. Configuration du backend ==&lt;br /&gt;
&lt;br /&gt;
=== Exemple HTTPS ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
backend back_ssl_projet_matomo&lt;br /&gt;
    server SSLPROJETMATOMO 10.0.0.X:443 check ssl verify none sni str(matomo.exemple.fr)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remplacer l&#039;adresse IP, le nom du serveur et le nom de domaine par les paramètres du projet.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Sécurité :&#039;&#039;&#039; `verify none` désactive la vérification du certificat présenté par le backend. Cette configuration existe sur AD64, mais ne doit pas être considérée comme une recommandation générale.&lt;br /&gt;
&lt;br /&gt;
Pour une nouvelle installation, privilégier une validation TLS du backend avec une autorité de certification appropriée lorsque l&#039;architecture le permet.&lt;br /&gt;
&lt;br /&gt;
=== Backend HTTP ===&lt;br /&gt;
&lt;br /&gt;
Un backend HTTP peut également être utilisé sur un réseau interne maîtrisé :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
backend back_projet_matomo&lt;br /&gt;
    server PROJETMATOMO 10.0.0.X:80 check&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le choix entre HTTP et HTTPS interne dépend de l&#039;architecture du projet et des exigences de sécurité.&lt;br /&gt;
&lt;br /&gt;
== 6. Certificats HTTPS ==&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;infrastructure AJLSM, les certificats publics HAProxy peuvent être gérés par `acme.sh`.&lt;br /&gt;
&lt;br /&gt;
Sur les serveurs HAProxy concernés, vérifier :&lt;br /&gt;
&lt;br /&gt;
* L&#039;existence du certificat pour le domaine Matomo.&lt;br /&gt;
* Sa date d&#039;expiration.&lt;br /&gt;
* La configuration de renouvellement automatique.&lt;br /&gt;
* Le mécanisme de déploiement du certificat dans HAProxy.&lt;br /&gt;
&lt;br /&gt;
Exemple de vérification depuis un poste client :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
openssl s_client \&lt;br /&gt;
  -connect matomo.exemple.fr:443 \&lt;br /&gt;
  -servername matomo.exemple.fr &amp;lt;/dev/null 2&amp;gt;/dev/null \&lt;br /&gt;
  | openssl x509 -noout -subject -issuer -dates&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La présence d&#039;une tâche automatique de renouvellement ne garantit pas à elle seule que le déploiement d&#039;un nouveau certificat fonctionnera. Le renouvellement et le rechargement effectif du certificat doivent être contrôlés.&lt;br /&gt;
&lt;br /&gt;
== 7. Déploiement avec Ansible ==&lt;br /&gt;
&lt;br /&gt;
=== Modification ===&lt;br /&gt;
&lt;br /&gt;
Depuis le Mac d&#039;administration :&lt;br /&gt;
&lt;br /&gt;
# Ouvrir le dépôt `ansible-ajlsm`.&lt;br /&gt;
# Modifier la configuration HAProxy dans les sources Ansible.&lt;br /&gt;
# Ajouter les ACL et le routage du nouveau domaine Matomo.&lt;br /&gt;
# Vérifier que les backends sont définis.&lt;br /&gt;
# Ne pas modifier directement les configurations générées sur les deux serveurs.&lt;br /&gt;
&lt;br /&gt;
=== Vérification de la syntaxe du playbook ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer --syntax-check&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Simulation du déploiement ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer --check --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier :&lt;br /&gt;
&lt;br /&gt;
* Que les modifications sont identiques sur les deux HAProxy.&lt;br /&gt;
* Que seuls les blocs attendus changent.&lt;br /&gt;
* Qu&#039;aucune configuration d&#039;un autre client n&#039;est modifiée.&lt;br /&gt;
* Qu&#039;aucune erreur n&#039;est signalée.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; le mode `--check` est une simulation. Il ne garantit pas à lui seul le succès du déploiement réel ni le comportement des ACL en production.&lt;br /&gt;
&lt;br /&gt;
=== Déploiement réel ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier le résultat du playbook sur les deux serveurs.&lt;br /&gt;
&lt;br /&gt;
Si le playbook prévoit un redémarrage ou un rechargement HAProxy, contrôler ensuite que les services restent actifs et que les applications existantes répondent normalement.&lt;br /&gt;
&lt;br /&gt;
== 8. Vérification depuis une connexion extérieure ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; effectuer les tests depuis une connexion qui n&#039;utilise ni l&#039;adresse IP publique du bureau ni le VPN AJLSM.&lt;br /&gt;
&lt;br /&gt;
Une connexion autorisée ne permet pas de vérifier correctement le refus d&#039;accès à l&#039;administration.&lt;br /&gt;
&lt;br /&gt;
=== Tester les ressources de suivi ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
MATOMO_URL=&amp;quot;https://matomo.exemple.fr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
for RESOURCE in matomo.js matomo.php; do&lt;br /&gt;
    echo &amp;quot;===== /$RESOURCE =====&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    curl -sS -o /dev/null -w &amp;quot;HTTP %{http_code}\n&amp;quot; \&lt;br /&gt;
        &amp;quot;$MATOMO_URL/$RESOURCE&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultats attendus pour l&#039;installation standard :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Ressource&lt;br /&gt;
! Résultat attendu&lt;br /&gt;
|-&lt;br /&gt;
| /matomo.js&lt;br /&gt;
| HTTP 200&lt;br /&gt;
|-&lt;br /&gt;
| /matomo.php&lt;br /&gt;
| Accessible sans HTTP 403 HAProxy&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Remarque :&#039;&#039;&#039; une réponse HTTP 200 de `matomo.php` sans paramètres de suivi ne constitue pas une preuve de collecte effective.&lt;br /&gt;
&lt;br /&gt;
=== Tester la protection de l&#039;administration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -sS -o /dev/null -w &amp;quot;HTTP %{http_code}\n&amp;quot; \&lt;br /&gt;
    &amp;quot;$MATOMO_URL/&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat attendu depuis une adresse IP extérieure non autorisée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
HTTP 403&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tester depuis une adresse autorisée ===&lt;br /&gt;
&lt;br /&gt;
Depuis le réseau AJLSM ou un accès VPN autorisé, vérifier que l&#039;interface Matomo reste accessible et que l&#039;authentification Matomo fonctionne.&lt;br /&gt;
&lt;br /&gt;
== 9. Vérification de la collecte ==&lt;br /&gt;
&lt;br /&gt;
Une fois les règles HAProxy appliquées :&lt;br /&gt;
&lt;br /&gt;
# Ouvrir une application Drupal ou Pleade suivie par Matomo.&lt;br /&gt;
# Naviguer sur plusieurs pages publiques.&lt;br /&gt;
# Vérifier l&#039;envoi des requêtes de suivi dans les outils réseau du navigateur.&lt;br /&gt;
# Vérifier l&#039;apparition des visites dans l&#039;interface Matomo.&lt;br /&gt;
&lt;br /&gt;
Pour une vérification directe en base :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT&lt;br /&gt;
    idsite,&lt;br /&gt;
    COUNT(*) AS visites,&lt;br /&gt;
    MAX(visit_last_action_time) AS derniere_activite&lt;br /&gt;
FROM matomo_log_visit&lt;br /&gt;
GROUP BY idsite;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette requête doit être exécutée dans la base Matomo avec un compte disposant des droits nécessaires.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Drupal]] et [[Matomo/Debug]].&lt;br /&gt;
&lt;br /&gt;
== 10. Exemple validé : AD64 — octobre 2026 ==&lt;br /&gt;
&lt;br /&gt;
=== Environnement ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Élément&lt;br /&gt;
! Valeur&lt;br /&gt;
|-&lt;br /&gt;
| Serveur Matomo&lt;br /&gt;
| ad64&lt;br /&gt;
|-&lt;br /&gt;
| Domaine&lt;br /&gt;
| ad64-matomo.pleade.com&lt;br /&gt;
|-&lt;br /&gt;
| Adresse privée de la VM&lt;br /&gt;
| 10.0.0.41&lt;br /&gt;
|-&lt;br /&gt;
| Backend HTTPS&lt;br /&gt;
| back_ssl_ad64_matomo&lt;br /&gt;
|-&lt;br /&gt;
| Répartiteurs&lt;br /&gt;
| haproxy-01 et haproxy-02&lt;br /&gt;
|-&lt;br /&gt;
| Applications suivies&lt;br /&gt;
| Drupal Internet et Drupal Salle de lecture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Configuration HAProxy ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;haproxy&amp;quot;&amp;gt;&lt;br /&gt;
# AD64 MATOMO&lt;br /&gt;
acl host_ad64_matomo hdr(host),host_only -i ad64-matomo.pleade.com&lt;br /&gt;
&lt;br /&gt;
# Points de collecte accessibles publiquement&lt;br /&gt;
acl ad64_matomo_tracking path -i /matomo.js /matomo.php&lt;br /&gt;
&lt;br /&gt;
# Administration réservée à AJLSM&lt;br /&gt;
http-request deny if host_ad64_matomo !allowed_ajlsm !ad64_matomo_tracking&lt;br /&gt;
&lt;br /&gt;
http-request redirect scheme https if host_ad64_matomo !{ ssl_fc }&lt;br /&gt;
&lt;br /&gt;
use_backend back_ssl_ad64_matomo if host_ad64_matomo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Backend HTTPS existant :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;haproxy&amp;quot;&amp;gt;&lt;br /&gt;
backend back_ssl_ad64_matomo&lt;br /&gt;
    server SSLAD64MATOMO 10.0.0.41:443 check ssl verify none sni str(ad64-matomo.pleade.com)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;ancien backend HTTP `back_ad64_matomo` a été conservé sans modification, bien qu&#039;il ne soit plus utilisé par ce routage.&lt;br /&gt;
&lt;br /&gt;
=== Résultats des tests ===&lt;br /&gt;
&lt;br /&gt;
Les vérifications réalisées le 20 octobre 2026 depuis une connexion extérieure au bureau ont donné :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Test&lt;br /&gt;
! Résultat&lt;br /&gt;
|-&lt;br /&gt;
| https://ad64-matomo.pleade.com/matomo.js&lt;br /&gt;
| HTTP 200&lt;br /&gt;
|-&lt;br /&gt;
| https://ad64-matomo.pleade.com/matomo.php&lt;br /&gt;
| HTTP 200&lt;br /&gt;
|-&lt;br /&gt;
| https://ad64-matomo.pleade.com/&lt;br /&gt;
| HTTP 403&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les visites Drupal Internet et Salle de lecture avaient également été enregistrées dans MariaDB, avec les identifiants Matomo 2 et 3.&lt;br /&gt;
&lt;br /&gt;
La collecte et la restriction d&#039;accès ont donc été vérifiées.&lt;br /&gt;
&lt;br /&gt;
== 11. Points de vigilance ==&lt;br /&gt;
&lt;br /&gt;
* Ne jamais ouvrir toute l&#039;interface Matomo à Internet uniquement pour permettre la collecte.&lt;br /&gt;
* Ne pas autoriser systématiquement les adresses IP du client à accéder à l&#039;administration.&lt;br /&gt;
* Ne pas bloquer les points de collecte nécessaires aux visiteurs.&lt;br /&gt;
* Ne pas modifier directement les fichiers HAProxy générés par Ansible.&lt;br /&gt;
* Tester depuis une véritable connexion extérieure.&lt;br /&gt;
* Vérifier le certificat HTTPS et son renouvellement.&lt;br /&gt;
* Vérifier que la collecte réelle fonctionne, au-delà du simple chargement du JavaScript.&lt;br /&gt;
&lt;br /&gt;
== 12. Maintenance et diagnostic ==&lt;br /&gt;
&lt;br /&gt;
En cas d&#039;anomalie, vérifier successivement :&lt;br /&gt;
&lt;br /&gt;
# La résolution DNS du domaine Matomo.&lt;br /&gt;
# Le certificat HTTPS présenté par HAProxy.&lt;br /&gt;
# La correspondance de l&#039;ACL `host`.&lt;br /&gt;
# Les règles `http-request deny`.&lt;br /&gt;
# Les chemins autorisés pour le suivi.&lt;br /&gt;
# L&#039;état du backend HAProxy.&lt;br /&gt;
# La disponibilité d&#039;Apache et PHP-FPM sur la VM.&lt;br /&gt;
# La réception effective des visites dans Matomo.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Debug]] et [[Matomo/Maintenance]].&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=Matomo/HAProxy&amp;diff=6508</id>
		<title>Matomo/HAProxy</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=Matomo/HAProxy&amp;diff=6508"/>
		<updated>2026-10-20T10:41:17Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : /* 5. Configuration du backend */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Publication et sécurisation de Matomo avec HAProxy =&lt;br /&gt;
&lt;br /&gt;
== Objectif ==&lt;br /&gt;
&lt;br /&gt;
Cette procédure décrit la publication d&#039;une instance Matomo derrière les répartiteurs HAProxy d&#039;AJLSM.&lt;br /&gt;
&lt;br /&gt;
Elle permet de :&lt;br /&gt;
&lt;br /&gt;
* Publier Matomo en HTTPS.&lt;br /&gt;
* Autoriser les requêtes de collecte des statistiques provenant des visiteurs.&lt;br /&gt;
* Réserver l&#039;interface d&#039;administration aux adresses IP autorisées.&lt;br /&gt;
* Déployer une configuration identique sur les deux HAProxy à l&#039;aide d&#039;Ansible.&lt;br /&gt;
* Vérifier le fonctionnement depuis une connexion extérieure.&lt;br /&gt;
&lt;br /&gt;
Cette procédure complète :&lt;br /&gt;
&lt;br /&gt;
* [[Matomo/Installation]]&lt;br /&gt;
* [[Matomo/Apache]]&lt;br /&gt;
* [[Matomo/Drupal]]&lt;br /&gt;
* [[Matomo/Debug]]&lt;br /&gt;
&lt;br /&gt;
== 1. Architecture ==&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;infrastructure AJLSM, le trafic suit généralement le chemin suivant :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Navigateur du visiteur&lt;br /&gt;
        |&lt;br /&gt;
        | HTTPS&lt;br /&gt;
        v&lt;br /&gt;
HAProxy (haproxy-01 / haproxy-02)&lt;br /&gt;
        |&lt;br /&gt;
        | HTTPS ou HTTP interne&lt;br /&gt;
        v&lt;br /&gt;
VM applicative&lt;br /&gt;
        |&lt;br /&gt;
        v&lt;br /&gt;
Apache + PHP-FPM + Matomo&lt;br /&gt;
        |&lt;br /&gt;
        v&lt;br /&gt;
MariaDB&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le navigateur charge le JavaScript Matomo et transmet les données de fréquentation au serveur Matomo.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; la collecte des statistiques doit fonctionner pour les visiteurs extérieurs, même lorsque l&#039;interface d&#039;administration Matomo est réservée à AJLSM.&lt;br /&gt;
&lt;br /&gt;
== 2. Prérequis ==&lt;br /&gt;
&lt;br /&gt;
Avant de modifier HAProxy, vérifier :&lt;br /&gt;
&lt;br /&gt;
* Que Matomo fonctionne sur la VM applicative.&lt;br /&gt;
* Que le VirtualHost Apache est configuré.&lt;br /&gt;
* Que le nom DNS public de Matomo est défini.&lt;br /&gt;
* Que le certificat HTTPS public est disponible sur HAProxy.&lt;br /&gt;
* Que le backend Matomo est joignable depuis les répartiteurs.&lt;br /&gt;
* Que l&#039;adresse IP ou le réseau autorisé pour l&#039;administration est connu.&lt;br /&gt;
&lt;br /&gt;
La configuration HAProxy est gérée par Ansible. Les modifications doivent être réalisées dans les fichiers sources du dépôt `ansible-ajlsm`, et non directement dans `/etc/haproxy/haproxy.cfg` sur les serveurs.&lt;br /&gt;
&lt;br /&gt;
== 3. Paramètres à personnaliser ==&lt;br /&gt;
&lt;br /&gt;
Pour chaque nouvelle installation, identifier les paramètres suivants :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Paramètre&lt;br /&gt;
! Exemple&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| Domaine Matomo&lt;br /&gt;
| matomo.exemple.fr&lt;br /&gt;
| Nom DNS public de Matomo&lt;br /&gt;
|-&lt;br /&gt;
| Backend&lt;br /&gt;
| back_ssl_projet_matomo&lt;br /&gt;
| Nom du backend HAProxy&lt;br /&gt;
|-&lt;br /&gt;
| Adresse de la VM&lt;br /&gt;
| 10.0.0.X&lt;br /&gt;
| Adresse privée de la VM hébergeant Matomo&lt;br /&gt;
|-&lt;br /&gt;
| Port backend&lt;br /&gt;
| 443&lt;br /&gt;
| Port HTTPS interne, si utilisé&lt;br /&gt;
|-&lt;br /&gt;
| ACL des administrateurs&lt;br /&gt;
| allowed_ajlsm&lt;br /&gt;
| Adresses IP autorisées à accéder à l&#039;interface&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 4. Configuration des ACL ==&lt;br /&gt;
&lt;br /&gt;
=== Principe ===&lt;br /&gt;
&lt;br /&gt;
Deux chemins sont nécessaires au suivi Matomo standard :&lt;br /&gt;
&lt;br /&gt;
* `/matomo.js` : chargement du JavaScript de suivi.&lt;br /&gt;
* `/matomo.php` : réception des données de fréquentation.&lt;br /&gt;
&lt;br /&gt;
Ces deux chemins doivent rester accessibles publiquement.&lt;br /&gt;
&lt;br /&gt;
Les autres chemins de l&#039;interface Matomo sont réservés aux adresses IP autorisées.&lt;br /&gt;
&lt;br /&gt;
=== Exemple générique ===&lt;br /&gt;
&lt;br /&gt;
Ajouter les règles suivantes dans le frontend HAProxy approprié :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;haproxy&amp;quot;&amp;gt;&lt;br /&gt;
# MATOMO - PROJET&lt;br /&gt;
acl host_projet_matomo hdr(host),host_only -i matomo.exemple.fr&lt;br /&gt;
&lt;br /&gt;
# Ressources de collecte accessibles publiquement&lt;br /&gt;
acl projet_matomo_tracking path -i /matomo.js /matomo.php&lt;br /&gt;
&lt;br /&gt;
# Interface Matomo réservée à AJLSM&lt;br /&gt;
http-request deny if host_projet_matomo !allowed_ajlsm !projet_matomo_tracking&lt;br /&gt;
&lt;br /&gt;
# Redirection HTTP vers HTTPS&lt;br /&gt;
http-request redirect scheme https if host_projet_matomo !{ ssl_fc }&lt;br /&gt;
&lt;br /&gt;
# Routage vers le backend Matomo&lt;br /&gt;
use_backend back_ssl_projet_matomo if host_projet_matomo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; cet exemple utilise l&#039;ACL `allowed_ajlsm` déjà présente dans l&#039;infrastructure AJLSM. Vérifier son existence et son contenu avant de déployer la configuration.&lt;br /&gt;
&lt;br /&gt;
L&#039;ACL `path -i` effectue une correspondance exacte des chemins. Elle ne rend pas accessibles les autres pages de l&#039;administration Matomo.&lt;br /&gt;
&lt;br /&gt;
Cette configuration est adaptée au suivi JavaScript standard. Si des fonctionnalités supplémentaires nécessitent d&#039;autres points d&#039;accès, leurs chemins doivent être étudiés séparément avant toute ouverture.&lt;br /&gt;
&lt;br /&gt;
== 5. Configuration du backend ==&lt;br /&gt;
&lt;br /&gt;
=== Exemple HTTPS ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
backend back_ssl_projet_matomo&lt;br /&gt;
    server SSLPROJETMATOMO 10.0.0.X:443 check ssl verify none sni str(matomo.exemple.fr)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remplacer l&#039;adresse IP, le nom du serveur et le nom de domaine par les paramètres du projet.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Sécurité :&#039;&#039;&#039; `verify none` désactive la vérification du certificat présenté par le backend. Cette configuration existe sur AD64, mais ne doit pas être considérée comme une recommandation générale.&lt;br /&gt;
&lt;br /&gt;
Pour une nouvelle installation, privilégier une validation TLS du backend avec une autorité de certification appropriée lorsque l&#039;architecture le permet.&lt;br /&gt;
&lt;br /&gt;
=== Backend HTTP ===&lt;br /&gt;
&lt;br /&gt;
Un backend HTTP peut également être utilisé sur un réseau interne maîtrisé :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;haproxy&amp;quot;&amp;gt;&lt;br /&gt;
backend back_projet_matomo&lt;br /&gt;
    server PROJETMATOMO 10.0.0.X:80 check&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le choix entre HTTP et HTTPS interne dépend de l&#039;architecture du projet et des exigences de sécurité.&lt;br /&gt;
&lt;br /&gt;
== 6. Certificats HTTPS ==&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;infrastructure AJLSM, les certificats publics HAProxy peuvent être gérés par `acme.sh`.&lt;br /&gt;
&lt;br /&gt;
Sur les serveurs HAProxy concernés, vérifier :&lt;br /&gt;
&lt;br /&gt;
* L&#039;existence du certificat pour le domaine Matomo.&lt;br /&gt;
* Sa date d&#039;expiration.&lt;br /&gt;
* La configuration de renouvellement automatique.&lt;br /&gt;
* Le mécanisme de déploiement du certificat dans HAProxy.&lt;br /&gt;
&lt;br /&gt;
Exemple de vérification depuis un poste client :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
openssl s_client \&lt;br /&gt;
  -connect matomo.exemple.fr:443 \&lt;br /&gt;
  -servername matomo.exemple.fr &amp;lt;/dev/null 2&amp;gt;/dev/null \&lt;br /&gt;
  | openssl x509 -noout -subject -issuer -dates&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La présence d&#039;une tâche automatique de renouvellement ne garantit pas à elle seule que le déploiement d&#039;un nouveau certificat fonctionnera. Le renouvellement et le rechargement effectif du certificat doivent être contrôlés.&lt;br /&gt;
&lt;br /&gt;
== 7. Déploiement avec Ansible ==&lt;br /&gt;
&lt;br /&gt;
=== Modification ===&lt;br /&gt;
&lt;br /&gt;
Depuis le Mac d&#039;administration :&lt;br /&gt;
&lt;br /&gt;
# Ouvrir le dépôt `ansible-ajlsm`.&lt;br /&gt;
# Modifier la configuration HAProxy dans les sources Ansible.&lt;br /&gt;
# Ajouter les ACL et le routage du nouveau domaine Matomo.&lt;br /&gt;
# Vérifier que les backends sont définis.&lt;br /&gt;
# Ne pas modifier directement les configurations générées sur les deux serveurs.&lt;br /&gt;
&lt;br /&gt;
=== Vérification de la syntaxe du playbook ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer --syntax-check&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Simulation du déploiement ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer --check --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier :&lt;br /&gt;
&lt;br /&gt;
* Que les modifications sont identiques sur les deux HAProxy.&lt;br /&gt;
* Que seuls les blocs attendus changent.&lt;br /&gt;
* Qu&#039;aucune configuration d&#039;un autre client n&#039;est modifiée.&lt;br /&gt;
* Qu&#039;aucune erreur n&#039;est signalée.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; le mode `--check` est une simulation. Il ne garantit pas à lui seul le succès du déploiement réel ni le comportement des ACL en production.&lt;br /&gt;
&lt;br /&gt;
=== Déploiement réel ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier le résultat du playbook sur les deux serveurs.&lt;br /&gt;
&lt;br /&gt;
Si le playbook prévoit un redémarrage ou un rechargement HAProxy, contrôler ensuite que les services restent actifs et que les applications existantes répondent normalement.&lt;br /&gt;
&lt;br /&gt;
== 8. Vérification depuis une connexion extérieure ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; effectuer les tests depuis une connexion qui n&#039;utilise ni l&#039;adresse IP publique du bureau ni le VPN AJLSM.&lt;br /&gt;
&lt;br /&gt;
Une connexion autorisée ne permet pas de vérifier correctement le refus d&#039;accès à l&#039;administration.&lt;br /&gt;
&lt;br /&gt;
=== Tester les ressources de suivi ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
MATOMO_URL=&amp;quot;https://matomo.exemple.fr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
for RESOURCE in matomo.js matomo.php; do&lt;br /&gt;
    echo &amp;quot;===== /$RESOURCE =====&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    curl -sS -o /dev/null -w &amp;quot;HTTP %{http_code}\n&amp;quot; \&lt;br /&gt;
        &amp;quot;$MATOMO_URL/$RESOURCE&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultats attendus pour l&#039;installation standard :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Ressource&lt;br /&gt;
! Résultat attendu&lt;br /&gt;
|-&lt;br /&gt;
| /matomo.js&lt;br /&gt;
| HTTP 200&lt;br /&gt;
|-&lt;br /&gt;
| /matomo.php&lt;br /&gt;
| Accessible sans HTTP 403 HAProxy&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Remarque :&#039;&#039;&#039; une réponse HTTP 200 de `matomo.php` sans paramètres de suivi ne constitue pas une preuve de collecte effective.&lt;br /&gt;
&lt;br /&gt;
=== Tester la protection de l&#039;administration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -sS -o /dev/null -w &amp;quot;HTTP %{http_code}\n&amp;quot; \&lt;br /&gt;
    &amp;quot;$MATOMO_URL/&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat attendu depuis une adresse IP extérieure non autorisée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
HTTP 403&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tester depuis une adresse autorisée ===&lt;br /&gt;
&lt;br /&gt;
Depuis le réseau AJLSM ou un accès VPN autorisé, vérifier que l&#039;interface Matomo reste accessible et que l&#039;authentification Matomo fonctionne.&lt;br /&gt;
&lt;br /&gt;
== 9. Vérification de la collecte ==&lt;br /&gt;
&lt;br /&gt;
Une fois les règles HAProxy appliquées :&lt;br /&gt;
&lt;br /&gt;
# Ouvrir une application Drupal ou Pleade suivie par Matomo.&lt;br /&gt;
# Naviguer sur plusieurs pages publiques.&lt;br /&gt;
# Vérifier l&#039;envoi des requêtes de suivi dans les outils réseau du navigateur.&lt;br /&gt;
# Vérifier l&#039;apparition des visites dans l&#039;interface Matomo.&lt;br /&gt;
&lt;br /&gt;
Pour une vérification directe en base :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT&lt;br /&gt;
    idsite,&lt;br /&gt;
    COUNT(*) AS visites,&lt;br /&gt;
    MAX(visit_last_action_time) AS derniere_activite&lt;br /&gt;
FROM matomo_log_visit&lt;br /&gt;
GROUP BY idsite;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette requête doit être exécutée dans la base Matomo avec un compte disposant des droits nécessaires.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Drupal]] et [[Matomo/Debug]].&lt;br /&gt;
&lt;br /&gt;
== 10. Exemple validé : AD64 — octobre 2026 ==&lt;br /&gt;
&lt;br /&gt;
=== Environnement ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Élément&lt;br /&gt;
! Valeur&lt;br /&gt;
|-&lt;br /&gt;
| Serveur Matomo&lt;br /&gt;
| ad64&lt;br /&gt;
|-&lt;br /&gt;
| Domaine&lt;br /&gt;
| ad64-matomo.pleade.com&lt;br /&gt;
|-&lt;br /&gt;
| Adresse privée de la VM&lt;br /&gt;
| 10.0.0.41&lt;br /&gt;
|-&lt;br /&gt;
| Backend HTTPS&lt;br /&gt;
| back_ssl_ad64_matomo&lt;br /&gt;
|-&lt;br /&gt;
| Répartiteurs&lt;br /&gt;
| haproxy-01 et haproxy-02&lt;br /&gt;
|-&lt;br /&gt;
| Applications suivies&lt;br /&gt;
| Drupal Internet et Drupal Salle de lecture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Configuration HAProxy ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;haproxy&amp;quot;&amp;gt;&lt;br /&gt;
# AD64 MATOMO&lt;br /&gt;
acl host_ad64_matomo hdr(host),host_only -i ad64-matomo.pleade.com&lt;br /&gt;
&lt;br /&gt;
# Points de collecte accessibles publiquement&lt;br /&gt;
acl ad64_matomo_tracking path -i /matomo.js /matomo.php&lt;br /&gt;
&lt;br /&gt;
# Administration réservée à AJLSM&lt;br /&gt;
http-request deny if host_ad64_matomo !allowed_ajlsm !ad64_matomo_tracking&lt;br /&gt;
&lt;br /&gt;
http-request redirect scheme https if host_ad64_matomo !{ ssl_fc }&lt;br /&gt;
&lt;br /&gt;
use_backend back_ssl_ad64_matomo if host_ad64_matomo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Backend HTTPS existant :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;haproxy&amp;quot;&amp;gt;&lt;br /&gt;
backend back_ssl_ad64_matomo&lt;br /&gt;
    server SSLAD64MATOMO 10.0.0.41:443 check ssl verify none sni str(ad64-matomo.pleade.com)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;ancien backend HTTP `back_ad64_matomo` a été conservé sans modification, bien qu&#039;il ne soit plus utilisé par ce routage.&lt;br /&gt;
&lt;br /&gt;
=== Résultats des tests ===&lt;br /&gt;
&lt;br /&gt;
Les vérifications réalisées le 20 octobre 2026 depuis une connexion extérieure au bureau ont donné :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Test&lt;br /&gt;
! Résultat&lt;br /&gt;
|-&lt;br /&gt;
| https://ad64-matomo.pleade.com/matomo.js&lt;br /&gt;
| HTTP 200&lt;br /&gt;
|-&lt;br /&gt;
| https://ad64-matomo.pleade.com/matomo.php&lt;br /&gt;
| HTTP 200&lt;br /&gt;
|-&lt;br /&gt;
| https://ad64-matomo.pleade.com/&lt;br /&gt;
| HTTP 403&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les visites Drupal Internet et Salle de lecture avaient également été enregistrées dans MariaDB, avec les identifiants Matomo 2 et 3.&lt;br /&gt;
&lt;br /&gt;
La collecte et la restriction d&#039;accès ont donc été vérifiées.&lt;br /&gt;
&lt;br /&gt;
== 11. Points de vigilance ==&lt;br /&gt;
&lt;br /&gt;
* Ne jamais ouvrir toute l&#039;interface Matomo à Internet uniquement pour permettre la collecte.&lt;br /&gt;
* Ne pas autoriser systématiquement les adresses IP du client à accéder à l&#039;administration.&lt;br /&gt;
* Ne pas bloquer les points de collecte nécessaires aux visiteurs.&lt;br /&gt;
* Ne pas modifier directement les fichiers HAProxy générés par Ansible.&lt;br /&gt;
* Tester depuis une véritable connexion extérieure.&lt;br /&gt;
* Vérifier le certificat HTTPS et son renouvellement.&lt;br /&gt;
* Vérifier que la collecte réelle fonctionne, au-delà du simple chargement du JavaScript.&lt;br /&gt;
&lt;br /&gt;
== 12. Maintenance et diagnostic ==&lt;br /&gt;
&lt;br /&gt;
En cas d&#039;anomalie, vérifier successivement :&lt;br /&gt;
&lt;br /&gt;
# La résolution DNS du domaine Matomo.&lt;br /&gt;
# Le certificat HTTPS présenté par HAProxy.&lt;br /&gt;
# La correspondance de l&#039;ACL `host`.&lt;br /&gt;
# Les règles `http-request deny`.&lt;br /&gt;
# Les chemins autorisés pour le suivi.&lt;br /&gt;
# L&#039;état du backend HAProxy.&lt;br /&gt;
# La disponibilité d&#039;Apache et PHP-FPM sur la VM.&lt;br /&gt;
# La réception effective des visites dans Matomo.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Debug]] et [[Matomo/Maintenance]].&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=Matomo/HAProxy&amp;diff=6507</id>
		<title>Matomo/HAProxy</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=Matomo/HAProxy&amp;diff=6507"/>
		<updated>2026-10-20T10:40:43Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : Page créée avec « = Publication et sécurisation de Matomo avec HAProxy =  == Objectif ==  Cette procédure décrit la publication d&amp;#039;une instance Matomo derrière les répartiteurs HAProxy ... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Publication et sécurisation de Matomo avec HAProxy =&lt;br /&gt;
&lt;br /&gt;
== Objectif ==&lt;br /&gt;
&lt;br /&gt;
Cette procédure décrit la publication d&#039;une instance Matomo derrière les répartiteurs HAProxy d&#039;AJLSM.&lt;br /&gt;
&lt;br /&gt;
Elle permet de :&lt;br /&gt;
&lt;br /&gt;
* Publier Matomo en HTTPS.&lt;br /&gt;
* Autoriser les requêtes de collecte des statistiques provenant des visiteurs.&lt;br /&gt;
* Réserver l&#039;interface d&#039;administration aux adresses IP autorisées.&lt;br /&gt;
* Déployer une configuration identique sur les deux HAProxy à l&#039;aide d&#039;Ansible.&lt;br /&gt;
* Vérifier le fonctionnement depuis une connexion extérieure.&lt;br /&gt;
&lt;br /&gt;
Cette procédure complète :&lt;br /&gt;
&lt;br /&gt;
* [[Matomo/Installation]]&lt;br /&gt;
* [[Matomo/Apache]]&lt;br /&gt;
* [[Matomo/Drupal]]&lt;br /&gt;
* [[Matomo/Debug]]&lt;br /&gt;
&lt;br /&gt;
== 1. Architecture ==&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;infrastructure AJLSM, le trafic suit généralement le chemin suivant :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Navigateur du visiteur&lt;br /&gt;
        |&lt;br /&gt;
        | HTTPS&lt;br /&gt;
        v&lt;br /&gt;
HAProxy (haproxy-01 / haproxy-02)&lt;br /&gt;
        |&lt;br /&gt;
        | HTTPS ou HTTP interne&lt;br /&gt;
        v&lt;br /&gt;
VM applicative&lt;br /&gt;
        |&lt;br /&gt;
        v&lt;br /&gt;
Apache + PHP-FPM + Matomo&lt;br /&gt;
        |&lt;br /&gt;
        v&lt;br /&gt;
MariaDB&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le navigateur charge le JavaScript Matomo et transmet les données de fréquentation au serveur Matomo.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; la collecte des statistiques doit fonctionner pour les visiteurs extérieurs, même lorsque l&#039;interface d&#039;administration Matomo est réservée à AJLSM.&lt;br /&gt;
&lt;br /&gt;
== 2. Prérequis ==&lt;br /&gt;
&lt;br /&gt;
Avant de modifier HAProxy, vérifier :&lt;br /&gt;
&lt;br /&gt;
* Que Matomo fonctionne sur la VM applicative.&lt;br /&gt;
* Que le VirtualHost Apache est configuré.&lt;br /&gt;
* Que le nom DNS public de Matomo est défini.&lt;br /&gt;
* Que le certificat HTTPS public est disponible sur HAProxy.&lt;br /&gt;
* Que le backend Matomo est joignable depuis les répartiteurs.&lt;br /&gt;
* Que l&#039;adresse IP ou le réseau autorisé pour l&#039;administration est connu.&lt;br /&gt;
&lt;br /&gt;
La configuration HAProxy est gérée par Ansible. Les modifications doivent être réalisées dans les fichiers sources du dépôt `ansible-ajlsm`, et non directement dans `/etc/haproxy/haproxy.cfg` sur les serveurs.&lt;br /&gt;
&lt;br /&gt;
== 3. Paramètres à personnaliser ==&lt;br /&gt;
&lt;br /&gt;
Pour chaque nouvelle installation, identifier les paramètres suivants :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Paramètre&lt;br /&gt;
! Exemple&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| Domaine Matomo&lt;br /&gt;
| matomo.exemple.fr&lt;br /&gt;
| Nom DNS public de Matomo&lt;br /&gt;
|-&lt;br /&gt;
| Backend&lt;br /&gt;
| back_ssl_projet_matomo&lt;br /&gt;
| Nom du backend HAProxy&lt;br /&gt;
|-&lt;br /&gt;
| Adresse de la VM&lt;br /&gt;
| 10.0.0.X&lt;br /&gt;
| Adresse privée de la VM hébergeant Matomo&lt;br /&gt;
|-&lt;br /&gt;
| Port backend&lt;br /&gt;
| 443&lt;br /&gt;
| Port HTTPS interne, si utilisé&lt;br /&gt;
|-&lt;br /&gt;
| ACL des administrateurs&lt;br /&gt;
| allowed_ajlsm&lt;br /&gt;
| Adresses IP autorisées à accéder à l&#039;interface&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 4. Configuration des ACL ==&lt;br /&gt;
&lt;br /&gt;
=== Principe ===&lt;br /&gt;
&lt;br /&gt;
Deux chemins sont nécessaires au suivi Matomo standard :&lt;br /&gt;
&lt;br /&gt;
* `/matomo.js` : chargement du JavaScript de suivi.&lt;br /&gt;
* `/matomo.php` : réception des données de fréquentation.&lt;br /&gt;
&lt;br /&gt;
Ces deux chemins doivent rester accessibles publiquement.&lt;br /&gt;
&lt;br /&gt;
Les autres chemins de l&#039;interface Matomo sont réservés aux adresses IP autorisées.&lt;br /&gt;
&lt;br /&gt;
=== Exemple générique ===&lt;br /&gt;
&lt;br /&gt;
Ajouter les règles suivantes dans le frontend HAProxy approprié :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;haproxy&amp;quot;&amp;gt;&lt;br /&gt;
# MATOMO - PROJET&lt;br /&gt;
acl host_projet_matomo hdr(host),host_only -i matomo.exemple.fr&lt;br /&gt;
&lt;br /&gt;
# Ressources de collecte accessibles publiquement&lt;br /&gt;
acl projet_matomo_tracking path -i /matomo.js /matomo.php&lt;br /&gt;
&lt;br /&gt;
# Interface Matomo réservée à AJLSM&lt;br /&gt;
http-request deny if host_projet_matomo !allowed_ajlsm !projet_matomo_tracking&lt;br /&gt;
&lt;br /&gt;
# Redirection HTTP vers HTTPS&lt;br /&gt;
http-request redirect scheme https if host_projet_matomo !{ ssl_fc }&lt;br /&gt;
&lt;br /&gt;
# Routage vers le backend Matomo&lt;br /&gt;
use_backend back_ssl_projet_matomo if host_projet_matomo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; cet exemple utilise l&#039;ACL `allowed_ajlsm` déjà présente dans l&#039;infrastructure AJLSM. Vérifier son existence et son contenu avant de déployer la configuration.&lt;br /&gt;
&lt;br /&gt;
L&#039;ACL `path -i` effectue une correspondance exacte des chemins. Elle ne rend pas accessibles les autres pages de l&#039;administration Matomo.&lt;br /&gt;
&lt;br /&gt;
Cette configuration est adaptée au suivi JavaScript standard. Si des fonctionnalités supplémentaires nécessitent d&#039;autres points d&#039;accès, leurs chemins doivent être étudiés séparément avant toute ouverture.&lt;br /&gt;
&lt;br /&gt;
== 5. Configuration du backend ==&lt;br /&gt;
&lt;br /&gt;
=== Exemple HTTPS ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;haproxy&amp;quot;&amp;gt;&lt;br /&gt;
backend back_ssl_projet_matomo&lt;br /&gt;
    server SSLPROJETMATOMO 10.0.0.X:443 check ssl verify none sni str(matomo.exemple.fr)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remplacer l&#039;adresse IP, le nom du serveur et le nom de domaine par les paramètres du projet.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Sécurité :&#039;&#039;&#039; `verify none` désactive la vérification du certificat présenté par le backend. Cette configuration existe sur AD64, mais ne doit pas être considérée comme une recommandation générale.&lt;br /&gt;
&lt;br /&gt;
Pour une nouvelle installation, privilégier une validation TLS du backend avec une autorité de certification appropriée lorsque l&#039;architecture le permet.&lt;br /&gt;
&lt;br /&gt;
=== Backend HTTP ===&lt;br /&gt;
&lt;br /&gt;
Un backend HTTP peut également être utilisé sur un réseau interne maîtrisé :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;haproxy&amp;quot;&amp;gt;&lt;br /&gt;
backend back_projet_matomo&lt;br /&gt;
    server PROJETMATOMO 10.0.0.X:80 check&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le choix entre HTTP et HTTPS interne dépend de l&#039;architecture du projet et des exigences de sécurité.&lt;br /&gt;
&lt;br /&gt;
== 6. Certificats HTTPS ==&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;infrastructure AJLSM, les certificats publics HAProxy peuvent être gérés par `acme.sh`.&lt;br /&gt;
&lt;br /&gt;
Sur les serveurs HAProxy concernés, vérifier :&lt;br /&gt;
&lt;br /&gt;
* L&#039;existence du certificat pour le domaine Matomo.&lt;br /&gt;
* Sa date d&#039;expiration.&lt;br /&gt;
* La configuration de renouvellement automatique.&lt;br /&gt;
* Le mécanisme de déploiement du certificat dans HAProxy.&lt;br /&gt;
&lt;br /&gt;
Exemple de vérification depuis un poste client :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
openssl s_client \&lt;br /&gt;
  -connect matomo.exemple.fr:443 \&lt;br /&gt;
  -servername matomo.exemple.fr &amp;lt;/dev/null 2&amp;gt;/dev/null \&lt;br /&gt;
  | openssl x509 -noout -subject -issuer -dates&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La présence d&#039;une tâche automatique de renouvellement ne garantit pas à elle seule que le déploiement d&#039;un nouveau certificat fonctionnera. Le renouvellement et le rechargement effectif du certificat doivent être contrôlés.&lt;br /&gt;
&lt;br /&gt;
== 7. Déploiement avec Ansible ==&lt;br /&gt;
&lt;br /&gt;
=== Modification ===&lt;br /&gt;
&lt;br /&gt;
Depuis le Mac d&#039;administration :&lt;br /&gt;
&lt;br /&gt;
# Ouvrir le dépôt `ansible-ajlsm`.&lt;br /&gt;
# Modifier la configuration HAProxy dans les sources Ansible.&lt;br /&gt;
# Ajouter les ACL et le routage du nouveau domaine Matomo.&lt;br /&gt;
# Vérifier que les backends sont définis.&lt;br /&gt;
# Ne pas modifier directement les configurations générées sur les deux serveurs.&lt;br /&gt;
&lt;br /&gt;
=== Vérification de la syntaxe du playbook ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer --syntax-check&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Simulation du déploiement ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer --check --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier :&lt;br /&gt;
&lt;br /&gt;
* Que les modifications sont identiques sur les deux HAProxy.&lt;br /&gt;
* Que seuls les blocs attendus changent.&lt;br /&gt;
* Qu&#039;aucune configuration d&#039;un autre client n&#039;est modifiée.&lt;br /&gt;
* Qu&#039;aucune erreur n&#039;est signalée.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; le mode `--check` est une simulation. Il ne garantit pas à lui seul le succès du déploiement réel ni le comportement des ACL en production.&lt;br /&gt;
&lt;br /&gt;
=== Déploiement réel ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml \&lt;br /&gt;
  --limit ajlsm_loadbalancer --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier le résultat du playbook sur les deux serveurs.&lt;br /&gt;
&lt;br /&gt;
Si le playbook prévoit un redémarrage ou un rechargement HAProxy, contrôler ensuite que les services restent actifs et que les applications existantes répondent normalement.&lt;br /&gt;
&lt;br /&gt;
== 8. Vérification depuis une connexion extérieure ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; effectuer les tests depuis une connexion qui n&#039;utilise ni l&#039;adresse IP publique du bureau ni le VPN AJLSM.&lt;br /&gt;
&lt;br /&gt;
Une connexion autorisée ne permet pas de vérifier correctement le refus d&#039;accès à l&#039;administration.&lt;br /&gt;
&lt;br /&gt;
=== Tester les ressources de suivi ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
MATOMO_URL=&amp;quot;https://matomo.exemple.fr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
for RESOURCE in matomo.js matomo.php; do&lt;br /&gt;
    echo &amp;quot;===== /$RESOURCE =====&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    curl -sS -o /dev/null -w &amp;quot;HTTP %{http_code}\n&amp;quot; \&lt;br /&gt;
        &amp;quot;$MATOMO_URL/$RESOURCE&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultats attendus pour l&#039;installation standard :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Ressource&lt;br /&gt;
! Résultat attendu&lt;br /&gt;
|-&lt;br /&gt;
| /matomo.js&lt;br /&gt;
| HTTP 200&lt;br /&gt;
|-&lt;br /&gt;
| /matomo.php&lt;br /&gt;
| Accessible sans HTTP 403 HAProxy&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Remarque :&#039;&#039;&#039; une réponse HTTP 200 de `matomo.php` sans paramètres de suivi ne constitue pas une preuve de collecte effective.&lt;br /&gt;
&lt;br /&gt;
=== Tester la protection de l&#039;administration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -sS -o /dev/null -w &amp;quot;HTTP %{http_code}\n&amp;quot; \&lt;br /&gt;
    &amp;quot;$MATOMO_URL/&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat attendu depuis une adresse IP extérieure non autorisée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
HTTP 403&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tester depuis une adresse autorisée ===&lt;br /&gt;
&lt;br /&gt;
Depuis le réseau AJLSM ou un accès VPN autorisé, vérifier que l&#039;interface Matomo reste accessible et que l&#039;authentification Matomo fonctionne.&lt;br /&gt;
&lt;br /&gt;
== 9. Vérification de la collecte ==&lt;br /&gt;
&lt;br /&gt;
Une fois les règles HAProxy appliquées :&lt;br /&gt;
&lt;br /&gt;
# Ouvrir une application Drupal ou Pleade suivie par Matomo.&lt;br /&gt;
# Naviguer sur plusieurs pages publiques.&lt;br /&gt;
# Vérifier l&#039;envoi des requêtes de suivi dans les outils réseau du navigateur.&lt;br /&gt;
# Vérifier l&#039;apparition des visites dans l&#039;interface Matomo.&lt;br /&gt;
&lt;br /&gt;
Pour une vérification directe en base :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT&lt;br /&gt;
    idsite,&lt;br /&gt;
    COUNT(*) AS visites,&lt;br /&gt;
    MAX(visit_last_action_time) AS derniere_activite&lt;br /&gt;
FROM matomo_log_visit&lt;br /&gt;
GROUP BY idsite;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette requête doit être exécutée dans la base Matomo avec un compte disposant des droits nécessaires.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Drupal]] et [[Matomo/Debug]].&lt;br /&gt;
&lt;br /&gt;
== 10. Exemple validé : AD64 — octobre 2026 ==&lt;br /&gt;
&lt;br /&gt;
=== Environnement ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Élément&lt;br /&gt;
! Valeur&lt;br /&gt;
|-&lt;br /&gt;
| Serveur Matomo&lt;br /&gt;
| ad64&lt;br /&gt;
|-&lt;br /&gt;
| Domaine&lt;br /&gt;
| ad64-matomo.pleade.com&lt;br /&gt;
|-&lt;br /&gt;
| Adresse privée de la VM&lt;br /&gt;
| 10.0.0.41&lt;br /&gt;
|-&lt;br /&gt;
| Backend HTTPS&lt;br /&gt;
| back_ssl_ad64_matomo&lt;br /&gt;
|-&lt;br /&gt;
| Répartiteurs&lt;br /&gt;
| haproxy-01 et haproxy-02&lt;br /&gt;
|-&lt;br /&gt;
| Applications suivies&lt;br /&gt;
| Drupal Internet et Drupal Salle de lecture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Configuration HAProxy ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;haproxy&amp;quot;&amp;gt;&lt;br /&gt;
# AD64 MATOMO&lt;br /&gt;
acl host_ad64_matomo hdr(host),host_only -i ad64-matomo.pleade.com&lt;br /&gt;
&lt;br /&gt;
# Points de collecte accessibles publiquement&lt;br /&gt;
acl ad64_matomo_tracking path -i /matomo.js /matomo.php&lt;br /&gt;
&lt;br /&gt;
# Administration réservée à AJLSM&lt;br /&gt;
http-request deny if host_ad64_matomo !allowed_ajlsm !ad64_matomo_tracking&lt;br /&gt;
&lt;br /&gt;
http-request redirect scheme https if host_ad64_matomo !{ ssl_fc }&lt;br /&gt;
&lt;br /&gt;
use_backend back_ssl_ad64_matomo if host_ad64_matomo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Backend HTTPS existant :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;haproxy&amp;quot;&amp;gt;&lt;br /&gt;
backend back_ssl_ad64_matomo&lt;br /&gt;
    server SSLAD64MATOMO 10.0.0.41:443 check ssl verify none sni str(ad64-matomo.pleade.com)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;ancien backend HTTP `back_ad64_matomo` a été conservé sans modification, bien qu&#039;il ne soit plus utilisé par ce routage.&lt;br /&gt;
&lt;br /&gt;
=== Résultats des tests ===&lt;br /&gt;
&lt;br /&gt;
Les vérifications réalisées le 20 octobre 2026 depuis une connexion extérieure au bureau ont donné :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Test&lt;br /&gt;
! Résultat&lt;br /&gt;
|-&lt;br /&gt;
| https://ad64-matomo.pleade.com/matomo.js&lt;br /&gt;
| HTTP 200&lt;br /&gt;
|-&lt;br /&gt;
| https://ad64-matomo.pleade.com/matomo.php&lt;br /&gt;
| HTTP 200&lt;br /&gt;
|-&lt;br /&gt;
| https://ad64-matomo.pleade.com/&lt;br /&gt;
| HTTP 403&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les visites Drupal Internet et Salle de lecture avaient également été enregistrées dans MariaDB, avec les identifiants Matomo 2 et 3.&lt;br /&gt;
&lt;br /&gt;
La collecte et la restriction d&#039;accès ont donc été vérifiées.&lt;br /&gt;
&lt;br /&gt;
== 11. Points de vigilance ==&lt;br /&gt;
&lt;br /&gt;
* Ne jamais ouvrir toute l&#039;interface Matomo à Internet uniquement pour permettre la collecte.&lt;br /&gt;
* Ne pas autoriser systématiquement les adresses IP du client à accéder à l&#039;administration.&lt;br /&gt;
* Ne pas bloquer les points de collecte nécessaires aux visiteurs.&lt;br /&gt;
* Ne pas modifier directement les fichiers HAProxy générés par Ansible.&lt;br /&gt;
* Tester depuis une véritable connexion extérieure.&lt;br /&gt;
* Vérifier le certificat HTTPS et son renouvellement.&lt;br /&gt;
* Vérifier que la collecte réelle fonctionne, au-delà du simple chargement du JavaScript.&lt;br /&gt;
&lt;br /&gt;
== 12. Maintenance et diagnostic ==&lt;br /&gt;
&lt;br /&gt;
En cas d&#039;anomalie, vérifier successivement :&lt;br /&gt;
&lt;br /&gt;
# La résolution DNS du domaine Matomo.&lt;br /&gt;
# Le certificat HTTPS présenté par HAProxy.&lt;br /&gt;
# La correspondance de l&#039;ACL `host`.&lt;br /&gt;
# Les règles `http-request deny`.&lt;br /&gt;
# Les chemins autorisés pour le suivi.&lt;br /&gt;
# L&#039;état du backend HAProxy.&lt;br /&gt;
# La disponibilité d&#039;Apache et PHP-FPM sur la VM.&lt;br /&gt;
# La réception effective des visites dans Matomo.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Debug]] et [[Matomo/Maintenance]].&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=Matomo&amp;diff=6506</id>
		<title>Matomo</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=Matomo&amp;diff=6506"/>
		<updated>2026-10-20T10:35:23Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : /* Matomo – Portails d&amp;#039;archives numériques */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Matomo – Portails d&#039;archives numériques =&lt;br /&gt;
&lt;br /&gt;
Documentation MediaWiki pour installer, configurer et exploiter Matomo&lt;br /&gt;
dans un portail basé sur :&lt;br /&gt;
&lt;br /&gt;
* Ubuntu 18.04 et sur Ubuntu 24.04&lt;br /&gt;
* Apache&lt;br /&gt;
* Haproxy&lt;br /&gt;
* PHP-FPM&lt;br /&gt;
* Drupal 10&lt;br /&gt;
* Pleade&lt;br /&gt;
* Lucene&lt;br /&gt;
* Mirador / IIIF&lt;br /&gt;
&lt;br /&gt;
== Sommaire ==&lt;br /&gt;
* [[Matomo/Installation]]&lt;br /&gt;
* [[Matomo/Apache]]&lt;br /&gt;
* [[Matomo/Drupal]]&lt;br /&gt;
* [[Matomo/HAProxy]]&lt;br /&gt;
* [[Matomo/Maintenance]]&lt;br /&gt;
* [[Matomo/Recherche]]&lt;br /&gt;
* [[Matomo/Pleade]]&lt;br /&gt;
* [[Matomo/IIIF]]&lt;br /&gt;
* [[Matomo/Evenements]]&lt;br /&gt;
* [[Matomo/Objectifs]]&lt;br /&gt;
* [[Matomo/Dashboards]]&lt;br /&gt;
* [[Matomo/Debug]]&lt;br /&gt;
* [[Matomo/KPI Archives]]&lt;br /&gt;
* [[Matomo/Lucene]]&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=Matomo/Drupal&amp;diff=6505</id>
		<title>Matomo/Drupal</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=Matomo/Drupal&amp;diff=6505"/>
		<updated>2026-10-20T10:30:22Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Intégration Matomo dans Drupal =&lt;br /&gt;
&lt;br /&gt;
== Objectif ==&lt;br /&gt;
&lt;br /&gt;
Configurer le module Matomo de Drupal pour transmettre les statistiques de fréquentation vers un serveur Matomo.&lt;br /&gt;
&lt;br /&gt;
Chaque application Drupal peut utiliser un identifiant de site Matomo distinct, même lorsque plusieurs applications partagent le même serveur Matomo.&lt;br /&gt;
&lt;br /&gt;
== 1. Prérequis ==&lt;br /&gt;
&lt;br /&gt;
* Matomo installé et accessible en HTTPS.&lt;br /&gt;
* Site déclaré dans l&#039;administration Matomo.&lt;br /&gt;
* Identifiant Matomo du site connu.&lt;br /&gt;
* Drupal fonctionnel.&lt;br /&gt;
* Composer et Drush disponibles.&lt;br /&gt;
* Module Drupal Matomo compatible avec la version de Drupal utilisée.&lt;br /&gt;
&lt;br /&gt;
== 2. Installation du module ==&lt;br /&gt;
&lt;br /&gt;
Se placer dans le répertoire racine du projet Drupal, contenant `composer.json`.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
composer require drupal/matomo&lt;br /&gt;
&lt;br /&gt;
./vendor/bin/drush --root=web en matomo -y&lt;br /&gt;
./vendor/bin/drush --root=web cache:rebuild&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; exécuter Composer avec le compte habituel de maintenance du projet Drupal, et non systématiquement sous `root` ou `www-data`.&lt;br /&gt;
&lt;br /&gt;
Adapter `--root=web` si le document root du projet est différent.&lt;br /&gt;
&lt;br /&gt;
== 3. Configuration de Matomo ==&lt;br /&gt;
&lt;br /&gt;
=== Paramètres du projet ===&lt;br /&gt;
&lt;br /&gt;
Définir les paramètres correspondant à l&#039;application :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
MATOMO_URL=&amp;quot;https://matomo.exemple.fr/&amp;quot;&lt;br /&gt;
MATOMO_SITE_ID=&amp;quot;1&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;identifiant doit correspondre au site créé dans l&#039;interface d&#039;administration Matomo.&lt;br /&gt;
&lt;br /&gt;
=== Configuration via Drush ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./vendor/bin/drush --root=web config:set matomo.settings \&lt;br /&gt;
    site_id &amp;quot;$MATOMO_SITE_ID&amp;quot; -y&lt;br /&gt;
&lt;br /&gt;
./vendor/bin/drush --root=web config:set matomo.settings &lt;br /&gt;
    url_http &amp;quot;$MATOMO_URL&amp;quot; -y&lt;br /&gt;
&lt;br /&gt;
./vendor/bin/drush --root=web config:set matomo.settings &lt;br /&gt;
    url_https &amp;quot;$MATOMO_URL&amp;quot; -y&lt;br /&gt;
&lt;br /&gt;
./vendor/bin/drush --root=web cache:rebuild&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Même si les paramètres portent les noms `url_http` et `url_https`, utiliser l&#039;adresse HTTPS du serveur Matomo lorsque celle-ci est disponible.&lt;br /&gt;
&lt;br /&gt;
== 4. Exclusion des pages d&#039;administration ==&lt;br /&gt;
&lt;br /&gt;
Il est généralement préférable de ne pas comptabiliser les consultations des pages d&#039;administration Drupal dans les statistiques publiques.&lt;br /&gt;
&lt;br /&gt;
=== Configuration standard ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./vendor/bin/drush --root=web config:set matomo.settings \&lt;br /&gt;
    visibility.request_path_pages \&lt;br /&gt;
    $&#039;/admin\n/admin/*\n/batch\n/node/add*\n/node/*/*\n/user/*/*&#039; -y&lt;br /&gt;
&lt;br /&gt;
./vendor/bin/drush --root=web cache:rebuild&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette configuration exclut les chemins indiqués lorsque le mode d&#039;exclusion est actif.&lt;br /&gt;
&lt;br /&gt;
=== Vérification du mode d&#039;exclusion ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./vendor/bin/drush --root=web config:get matomo.settings \&lt;br /&gt;
    visibility.request_path_mode&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sur les installations AD64 validées en octobre 2026, la valeur utilisée est `0`.&lt;br /&gt;
&lt;br /&gt;
=== Cas des chemins d&#039;administration renommés ===&lt;br /&gt;
&lt;br /&gt;
Certains projets Drupal utilisent le module `rename_admin_paths` pour modifier les chemins d&#039;administration.&lt;br /&gt;
&lt;br /&gt;
Exemple AD64 :&lt;br /&gt;
&lt;br /&gt;
* `/admin` devient `/bacad64`.&lt;br /&gt;
* `/user` devient `/arc-ad64`.&lt;br /&gt;
&lt;br /&gt;
Dans ce cas, ajouter les chemins personnalisés à la liste d&#039;exclusion.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./vendor/bin/drush --root=web config:set matomo.settings \&lt;br /&gt;
    visibility.request_path_pages \&lt;br /&gt;
    $&#039;/admin\n/admin/*\n/bacad64\n/bacad64/*\n/batch\n/node/add*\n/node/*/*\n/user/*/*\n/arc-ad64\n/arc-ad64/*&#039; -y&lt;br /&gt;
&lt;br /&gt;
./vendor/bin/drush --root=web cache:rebuild&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; les chemins `/bacad64` et `/arc-ad64` sont propres à l&#039;exemple AD64. Ils doivent être remplacés par les chemins réellement configurés sur chaque projet.&lt;br /&gt;
&lt;br /&gt;
== 5. Gestion des utilisateurs et de la confidentialité ==&lt;br /&gt;
&lt;br /&gt;
Le module Drupal Matomo propose plusieurs paramètres de visibilité et de confidentialité.&lt;br /&gt;
&lt;br /&gt;
Vérifier les valeurs en vigueur :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./vendor/bin/drush --root=web config:get matomo.settings&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Paramètres notamment concernés :&lt;br /&gt;
&lt;br /&gt;
* `visibility.user_account_mode`&lt;br /&gt;
* `visibility.user_role_mode`&lt;br /&gt;
* `visibility.user_role_roles`&lt;br /&gt;
* `privacy.donottrack`&lt;br /&gt;
* `privacy.disablecookies`&lt;br /&gt;
&lt;br /&gt;
La documentation historique AJLSM utilisait notamment :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
drush config:set matomo.settings visibility.user_account_mode 0 -y&lt;br /&gt;
drush config:set matomo.settings visibility.user_role_mode 0 -y&lt;br /&gt;
drush config:set matomo.settings privacy.donottrack false -y&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ces valeurs ne doivent pas être réappliquées systématiquement.&lt;br /&gt;
&lt;br /&gt;
Sur AD64, le paramètre `privacy.donottrack` était configuré à `true` lors de la vérification d&#039;octobre 2026.&lt;br /&gt;
&lt;br /&gt;
La politique de suivi, de cookies et de respect du signal Do Not Track doit être déterminée selon les exigences applicables au projet.&lt;br /&gt;
&lt;br /&gt;
== 6. Recherche interne Drupal ==&lt;br /&gt;
&lt;br /&gt;
Le module Matomo permet de suivre les recherches internes Drupal.&lt;br /&gt;
&lt;br /&gt;
Activation, lorsque cette fonctionnalité est nécessaire :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./vendor/bin/drush --root=web config:set matomo.settings \&lt;br /&gt;
    track.site_search true -y&lt;br /&gt;
&lt;br /&gt;
./vendor/bin/drush --root=web cache:rebuild&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; l&#039;activation de ce paramètre ne garantit pas à elle seule que toutes les recherches seront reconnues correctement. Vérifier le fonctionnement réel du moteur de recherche Drupal et les paramètres transmis à Matomo.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Recherche]].&lt;br /&gt;
&lt;br /&gt;
== 7. Vérification de l&#039;injection JavaScript ==&lt;br /&gt;
&lt;br /&gt;
Définir l&#039;URL publique de l&#039;application Drupal :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
DRUPAL_URL=&amp;quot;https://drupal.exemple.fr/&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier la présence du code de suivi :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -sSL &amp;quot;$DRUPAL_URL&amp;quot; \&lt;br /&gt;
    | grep -iE &#039;matomo.js|matomo.php|_paq|setSiteId&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier que l&#039;identifiant Matomo injecté correspond bien à celui du site Drupal concerné.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; cette vérification confirme uniquement la présence du code de suivi dans la page HTML. Elle ne prouve pas que Matomo reçoit les visites.&lt;br /&gt;
&lt;br /&gt;
== 8. Vérification de la collecte réelle ==&lt;br /&gt;
&lt;br /&gt;
=== Test navigateur ===&lt;br /&gt;
&lt;br /&gt;
# Ouvrir le site Drupal dans un navigateur.&lt;br /&gt;
# Consulter plusieurs pages publiques.&lt;br /&gt;
# Éviter, pour ce test, une session d&#039;administration Drupal.&lt;br /&gt;
# Vérifier l&#039;apparition des visites dans Matomo.&lt;br /&gt;
&lt;br /&gt;
Les bloqueurs de publicité, les paramètres de confidentialité du navigateur ou les restrictions réseau peuvent empêcher la collecte.&lt;br /&gt;
&lt;br /&gt;
=== Vérification dans MariaDB ===&lt;br /&gt;
&lt;br /&gt;
Sur le serveur Matomo, adapter le nom de la base et les identifiants des sites :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo mariadb -t -e &amp;quot;&lt;br /&gt;
SELECT&lt;br /&gt;
    idsite,&lt;br /&gt;
    COUNT(*) AS visites,&lt;br /&gt;
    MAX(visit_last_action_time) AS derniere_activite&lt;br /&gt;
FROM matomo.matomo_log_visit&lt;br /&gt;
WHERE idsite IN (2,3)&lt;br /&gt;
GROUP BY idsite;&lt;br /&gt;
&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette requête permet de vérifier que des visites ont été enregistrées.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; les identifiants `2` et `3` sont ceux de l&#039;exemple AD64. Ils doivent être adaptés aux sites Matomo du projet.&lt;br /&gt;
&lt;br /&gt;
== 9. Exemple : AD64 ==&lt;br /&gt;
&lt;br /&gt;
En octobre 2026, les deux applications Drupal AD64 ont été configurées indépendamment.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Application&lt;br /&gt;
! Répertoire Drupal&lt;br /&gt;
! Identifiant Matomo&lt;br /&gt;
|-&lt;br /&gt;
| Internet&lt;br /&gt;
| /home/ajlsm/drupals/internet&lt;br /&gt;
| 2&lt;br /&gt;
|-&lt;br /&gt;
| Salle de lecture&lt;br /&gt;
| /home/ajlsm/drupals/slecture&lt;br /&gt;
| 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Serveur Matomo commun :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
https://ad64-matomo.pleade.com/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les deux applications disposent :&lt;br /&gt;
&lt;br /&gt;
* Du module Drupal Matomo activé.&lt;br /&gt;
* De leur propre identifiant Matomo.&lt;br /&gt;
* D&#039;exclusions des chemins d&#039;administration.&lt;br /&gt;
* D&#039;une collecte vérifiée par consultation des données MariaDB.&lt;br /&gt;
&lt;br /&gt;
L&#039;application de préproduction n&#039;a pas été configurée pour le suivi Matomo, celui-ci n&#039;étant pas nécessaire à son utilisation.&lt;br /&gt;
&lt;br /&gt;
== 10. Diagnostic ==&lt;br /&gt;
&lt;br /&gt;
Si aucune visite n&#039;apparaît dans Matomo :&lt;br /&gt;
&lt;br /&gt;
# Vérifier l&#039;identifiant du site Matomo.&lt;br /&gt;
# Vérifier les URL configurées dans Drupal.&lt;br /&gt;
# Vérifier la présence du JavaScript dans les pages publiques.&lt;br /&gt;
# Vérifier les requêtes réseau vers `matomo.php`.&lt;br /&gt;
# Vérifier les ACL HAProxy.&lt;br /&gt;
# Vérifier les éventuels bloqueurs ou restrictions de confidentialité.&lt;br /&gt;
# Vérifier les journaux Apache et les données MariaDB.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Debug]] et [[Matomo/HAProxy]].&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=Matomo/Apache&amp;diff=6504</id>
		<title>Matomo/Apache</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=Matomo/Apache&amp;diff=6504"/>
		<updated>2026-10-20T10:29:59Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Configuration Apache pour Matomo =&lt;br /&gt;
&lt;br /&gt;
== Objectif ==&lt;br /&gt;
&lt;br /&gt;
Configurer Apache pour publier une installation Matomo située dans `/var/www/matomo`.&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;infrastructure AJLSM, Matomo peut être accessible :&lt;br /&gt;
&lt;br /&gt;
* Directement via Apache, avec un certificat HTTPS local.&lt;br /&gt;
* Derrière les répartiteurs HAProxy, qui assurent le HTTPS public et les restrictions d&#039;accès.&lt;br /&gt;
&lt;br /&gt;
La configuration des ACL et des certificats HAProxy est décrite dans [[Matomo/HAProxy]].&lt;br /&gt;
&lt;br /&gt;
== 1. Prérequis ==&lt;br /&gt;
&lt;br /&gt;
* Matomo installé dans `/var/www/matomo`.&lt;br /&gt;
* Apache 2.4 installé et actif.&lt;br /&gt;
* PHP-FPM installé et configuré.&lt;br /&gt;
* Nom DNS prévu pour Matomo.&lt;br /&gt;
* Base MariaDB configurée.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Installation]].&lt;br /&gt;
&lt;br /&gt;
== 2. Création du VirtualHost ==&lt;br /&gt;
&lt;br /&gt;
Créer le fichier `/etc/apache2/sites-available/matomo.conf`.&lt;br /&gt;
&lt;br /&gt;
=== Exemple HTTP ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;apache&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
    ServerName matomo.exemple.fr&lt;br /&gt;
    DocumentRoot /var/www/matomo&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;Directory /var/www/matomo&amp;gt;&lt;br /&gt;
        Options FollowSymLinks&lt;br /&gt;
        AllowOverride All&lt;br /&gt;
        Require all granted&lt;br /&gt;
    &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    ErrorLog ${APACHE_LOG_DIR}/matomo-error.log&lt;br /&gt;
    CustomLog ${APACHE_LOG_DIR}/matomo-access.log combined&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remplacer `matomo.exemple.fr` par le nom DNS du projet.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; cet exemple configure uniquement le VirtualHost HTTP. Il ne constitue pas, à lui seul, une publication sécurisée sur Internet.&lt;br /&gt;
&lt;br /&gt;
== 3. Configuration PHP-FPM ==&lt;br /&gt;
&lt;br /&gt;
Vérifier que PHP-FPM est actif :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl status php8.4-fpm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Adapter la version de PHP à celle installée sur la VM.&lt;br /&gt;
&lt;br /&gt;
Vérifier les modules Apache :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apache2ctl -M | grep -E &#039;proxy|fcgi|rewrite&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Si nécessaire :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo a2enmod proxy_fcgi setenvif rewrite&lt;br /&gt;
sudo a2enconf php8.4-fpm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; si plusieurs applications utilisent des versions PHP différentes, ne pas activer automatiquement une configuration PHP-FPM globale. Utiliser le pool et le gestionnaire PHP appropriés au VirtualHost.&lt;br /&gt;
&lt;br /&gt;
== 4. Activation du VirtualHost ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo a2ensite matomo.conf&lt;br /&gt;
sudo apache2ctl configtest&lt;br /&gt;
sudo systemctl reload apache2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat attendu pour `configtest` :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Syntax OK&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 5. Configuration HTTPS ==&lt;br /&gt;
&lt;br /&gt;
=== HTTPS directement sur Apache ===&lt;br /&gt;
&lt;br /&gt;
Lorsque Matomo est publié directement par Apache, configurer un VirtualHost HTTPS et un certificat valide.&lt;br /&gt;
&lt;br /&gt;
Une installation Certbot peut être utilisée si elle correspond à l&#039;architecture du serveur :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install certbot python3-certbot-apache&lt;br /&gt;
sudo certbot --apache&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== HTTPS via HAProxy ===&lt;br /&gt;
&lt;br /&gt;
Lorsque Matomo est publié derrière HAProxy :&lt;br /&gt;
&lt;br /&gt;
* Le domaine public pointe vers HAProxy.&lt;br /&gt;
* HAProxy présente le certificat HTTPS public.&lt;br /&gt;
* HAProxy transmet les requêtes au backend Apache.&lt;br /&gt;
* Le backend peut utiliser HTTP ou HTTPS selon la configuration du projet.&lt;br /&gt;
&lt;br /&gt;
Dans le cas d&#039;un backend HTTPS, vérifier le certificat utilisé côté Apache et la configuration de validation TLS du backend HAProxy.&lt;br /&gt;
&lt;br /&gt;
Ne pas installer automatiquement un second certificat public sur Apache si ce n&#039;est pas nécessaire.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/HAProxy]].&lt;br /&gt;
&lt;br /&gt;
== 6. Protection des fichiers sensibles ==&lt;br /&gt;
&lt;br /&gt;
Le répertoire Matomo contient des fichiers qui ne doivent pas être accessibles directement depuis le navigateur, notamment les fichiers de configuration.&lt;br /&gt;
&lt;br /&gt;
Vérifier que les règles de protection fournies avec Matomo sont effectivement appliquées par Apache.&lt;br /&gt;
&lt;br /&gt;
La directive suivante autorise Apache à prendre en compte les fichiers `.htaccess` de l&#039;application :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;apache&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;Directory /var/www/matomo&amp;gt;&lt;br /&gt;
    AllowOverride All&lt;br /&gt;
    Require all granted&lt;br /&gt;
&amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; `AllowOverride All` ne remplace pas une vérification effective de la protection des fichiers sensibles.&lt;br /&gt;
&lt;br /&gt;
Les permissions système sont décrites dans [[Matomo/Installation]].&lt;br /&gt;
&lt;br /&gt;
== 7. Vérifications ==&lt;br /&gt;
&lt;br /&gt;
=== Vérifier la configuration Apache ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apache2ctl configtest&lt;br /&gt;
sudo apache2ctl -S&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Vérifier la réponse HTTP ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
MATOMO_URL=&amp;quot;https://matomo.exemple.fr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl -sS -o /dev/null -w &amp;quot;HTTP %{http_code}\n&amp;quot; &lt;br /&gt;
    &amp;quot;$MATOMO_URL/matomo.js&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl -sS -o /dev/null -w &amp;quot;HTTP %{http_code}\n&amp;quot; &lt;br /&gt;
    &amp;quot;$MATOMO_URL/matomo.php&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les deux points de collecte doivent être accessibles aux visiteurs autorisés à consulter les applications suivies.&lt;br /&gt;
&lt;br /&gt;
Une réponse HTTP 200 sur `matomo.php` ne prouve pas à elle seule qu&#039;une visite a été enregistrée.&lt;br /&gt;
&lt;br /&gt;
=== Vérifier les journaux ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo tail -n 50 /var/log/apache2/matomo-error.log&lt;br /&gt;
sudo tail -n 50 /var/log/apache2/matomo-access.log&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Adapter les chemins si les journaux du projet utilisent d&#039;autres noms.&lt;br /&gt;
&lt;br /&gt;
== 8. Cas d&#039;une publication sécurisée par HAProxy ==&lt;br /&gt;
&lt;br /&gt;
Dans les installations AJLSM où l&#039;administration Matomo est réservée à certaines adresses IP :&lt;br /&gt;
&lt;br /&gt;
* `/matomo.js` doit rester accessible pour le chargement du script de suivi.&lt;br /&gt;
* `/matomo.php` doit rester accessible pour la transmission des statistiques.&lt;br /&gt;
* L&#039;interface Matomo doit être protégée par les ACL HAProxy.&lt;br /&gt;
* Les autres chemins doivent être examinés selon les fonctionnalités utilisées.&lt;br /&gt;
&lt;br /&gt;
La restriction par IP de l&#039;interface ne remplace pas l&#039;authentification propre à Matomo.&lt;br /&gt;
&lt;br /&gt;
La procédure de configuration et de déploiement Ansible est détaillée dans [[Matomo/HAProxy]].&lt;br /&gt;
&lt;br /&gt;
== 9. Diagnostic ==&lt;br /&gt;
&lt;br /&gt;
En cas de dysfonctionnement, vérifier successivement :&lt;br /&gt;
&lt;br /&gt;
# La résolution DNS.&lt;br /&gt;
# La validité du certificat HTTPS.&lt;br /&gt;
# Le routage HAProxy, si utilisé.&lt;br /&gt;
# La configuration du VirtualHost Apache.&lt;br /&gt;
# Le fonctionnement de PHP-FPM.&lt;br /&gt;
# Les permissions de `/var/www/matomo`.&lt;br /&gt;
# La connexion à MariaDB.&lt;br /&gt;
# Les journaux Apache et PHP-FPM.&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Debug]].&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=Matomo/Installation&amp;diff=6503</id>
		<title>Matomo/Installation</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=Matomo/Installation&amp;diff=6503"/>
		<updated>2026-10-20T10:28:13Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : /* 5. Installation des fichiers Matomo */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Installation de Matomo sur une VM Ubuntu =&lt;br /&gt;
&lt;br /&gt;
== Objectif ==&lt;br /&gt;
&lt;br /&gt;
Cette procédure décrit l&#039;installation de Matomo sur les VM AJLSM hébergeant les applications Pleade et Drupal.&lt;br /&gt;
&lt;br /&gt;
Elle est destinée à être réutilisée pour les nouveaux projets, indépendamment du client et du nom de domaine.&lt;br /&gt;
&lt;br /&gt;
La configuration Apache, l&#039;intégration Drupal et la publication sécurisée par HAProxy sont détaillées dans des chapitres distincts :&lt;br /&gt;
&lt;br /&gt;
* [[Matomo/Apache]]&lt;br /&gt;
* [[Matomo/Drupal]]&lt;br /&gt;
* [[Matomo/HAProxy]]&lt;br /&gt;
* [[Matomo/Maintenance]]&lt;br /&gt;
&lt;br /&gt;
== 1. Environnement technique ==&lt;br /&gt;
&lt;br /&gt;
=== Versions d&#039;Ubuntu et de PHP ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Ubuntu&lt;br /&gt;
! PHP&lt;br /&gt;
! Statut documentaire&lt;br /&gt;
|-&lt;br /&gt;
| Ubuntu 18.04&lt;br /&gt;
| PHP 8.1 via PHP-FPM&lt;br /&gt;
| Installation historique, hors support standard&lt;br /&gt;
|-&lt;br /&gt;
| Ubuntu 24.04&lt;br /&gt;
| PHP 8.3 via PHP-FPM&lt;br /&gt;
| Installation existante&lt;br /&gt;
|-&lt;br /&gt;
| Ubuntu 26.04&lt;br /&gt;
| PHP 8.4 via PHP-FPM&lt;br /&gt;
| Environnement utilisé pour AD64 en octobre 2026&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; vérifier la compatibilité entre la version de Matomo et celle de PHP avant toute nouvelle installation ou mise à jour.&lt;br /&gt;
&lt;br /&gt;
=== Composants nécessaires ===&lt;br /&gt;
&lt;br /&gt;
* Apache 2.4&lt;br /&gt;
* PHP-FPM&lt;br /&gt;
* MariaDB ou MySQL&lt;br /&gt;
* Extensions PHP requises par Matomo&lt;br /&gt;
* Accès HTTPS, directement ou via HAProxy&lt;br /&gt;
* Accès réseau permettant le téléchargement et les mises à jour de Matomo&lt;br /&gt;
&lt;br /&gt;
== 2. Installation des dépendances PHP ==&lt;br /&gt;
&lt;br /&gt;
Adapter la version de PHP à celle installée sur la VM.&lt;br /&gt;
&lt;br /&gt;
=== Ubuntu 24.04 — PHP 8.3 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install \&lt;br /&gt;
  php8.3-mysql php8.3-gd php8.3-curl php8.3-xml \&lt;br /&gt;
  php8.3-mbstring php8.3-zip php8.3-intl&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ubuntu 26.04 — PHP 8.4 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install \&lt;br /&gt;
  php8.4-mysql php8.4-gd php8.4-curl php8.4-xml \&lt;br /&gt;
  php8.4-mbstring php8.4-zip php8.4-intl&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Vérification ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php -v&lt;br /&gt;
php -m | grep -Ei &#039;mysqli|pdo_mysql|gd|curl|mbstring|xml|zip|intl&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3. Activation de PHP-FPM ==&lt;br /&gt;
&lt;br /&gt;
Exemple pour PHP 8.4 :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install php8.4-fpm&lt;br /&gt;
sudo a2enmod proxy_fcgi setenvif&lt;br /&gt;
sudo a2enconf php8.4-fpm&lt;br /&gt;
sudo systemctl reload apache2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier le service :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl status php8.4-fpm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; sur une VM hébergeant plusieurs applications PHP, vérifier les configurations Apache existantes avant d&#039;activer une configuration PHP-FPM globale.&lt;br /&gt;
&lt;br /&gt;
== 4. Préparation de MariaDB ==&lt;br /&gt;
&lt;br /&gt;
Vérifier que MariaDB est installé et actif :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl status mariadb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Matomo nécessite :&lt;br /&gt;
&lt;br /&gt;
* Une base de données dédiée&lt;br /&gt;
* Un utilisateur SQL dédié&lt;br /&gt;
* Des droits limités à cette base&lt;br /&gt;
&lt;br /&gt;
Exemple générique à adapter :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
CREATE DATABASE matomo&lt;br /&gt;
  CHARACTER SET utf8mb4&lt;br /&gt;
  COLLATE utf8mb4_unicode_ci;&lt;br /&gt;
&lt;br /&gt;
CREATE USER &#039;matomo&#039;@&#039;localhost&#039;&lt;br /&gt;
  IDENTIFIED BY &#039;MOT_DE_PASSE_FORT_A_REMPLACER&#039;;&lt;br /&gt;
&lt;br /&gt;
GRANT ALL PRIVILEGES ON matomo.*&lt;br /&gt;
  TO &#039;matomo&#039;@&#039;localhost&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ne jamais conserver le mot de passe d&#039;exemple dans une installation réelle.&lt;br /&gt;
&lt;br /&gt;
== 5. Permissions et sécurisation des fichiers Matomo ==&lt;br /&gt;
&lt;br /&gt;
=== Principes ===&lt;br /&gt;
&lt;br /&gt;
L&#039;installation Matomo est située dans :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/var/www/matomo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sur les VM AJLSM, lorsque PHP-FPM s&#039;exécute sous l&#039;utilisateur `www-data`, les fichiers de Matomo appartiennent normalement à `www-data:www-data`.&lt;br /&gt;
&lt;br /&gt;
Les permissions de référence sont :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Élément&lt;br /&gt;
! Permissions&lt;br /&gt;
! Observations&lt;br /&gt;
|-&lt;br /&gt;
| Répertoires de l&#039;application&lt;br /&gt;
| 755&lt;br /&gt;
| Lecture et traversée autorisées ; écriture réservée au propriétaire&lt;br /&gt;
|-&lt;br /&gt;
| Fichiers de l&#039;application&lt;br /&gt;
| 644&lt;br /&gt;
| Lecture autorisée ; écriture réservée au propriétaire&lt;br /&gt;
|-&lt;br /&gt;
| config/config.ini.php&lt;br /&gt;
| 600&lt;br /&gt;
| Fichier sensible contenant notamment les paramètres de connexion à MariaDB&lt;br /&gt;
|-&lt;br /&gt;
| Répertoires temporaires et de configuration&lt;br /&gt;
| 755&lt;br /&gt;
| Accessibles en écriture au compte PHP-FPM lorsqu&#039;il en est propriétaire&lt;br /&gt;
|-&lt;br /&gt;
| .well-known/acme-challenge&lt;br /&gt;
| 755&lt;br /&gt;
| Peut appartenir à root:root ; ne pas modifier sans vérifier la configuration ACME&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; les permissions 755 et 644 ne rendent pas les fichiers accessibles en écriture à tous. Elles permettent uniquement au propriétaire de les modifier.&lt;br /&gt;
&lt;br /&gt;
=== Configuration initiale ===&lt;br /&gt;
&lt;br /&gt;
Pour une nouvelle installation dont l&#039;ensemble des fichiers applicatifs doit appartenir à `www-data` :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo chown -R www-data:www-data /var/www/matomo&lt;br /&gt;
&lt;br /&gt;
sudo find /var/www/matomo -type d -exec chmod 755 {} \;&lt;br /&gt;
sudo find /var/www/matomo -type f -exec chmod 644 {} \;&lt;br /&gt;
&lt;br /&gt;
sudo chmod 600 /var/www/matomo/config/config.ini.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; ces commandes concernent une installation initiale, avant la création éventuelle de répertoires spécifiques par d&#039;autres services. Ne pas les réexécuter aveuglément sur une installation existante.&lt;br /&gt;
&lt;br /&gt;
Vérifier préalablement le compte utilisé par PHP-FPM. Si celui-ci est différent de `www-data`, adapter les propriétaires et permissions.&lt;br /&gt;
&lt;br /&gt;
=== Vérification des permissions ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
stat -c &#039;%A %a %U:%G %n&#039; \&lt;br /&gt;
  /var/www/matomo \&lt;br /&gt;
  /var/www/matomo/config \&lt;br /&gt;
  /var/www/matomo/config/config.ini.php \&lt;br /&gt;
  /var/www/matomo/tmp \&lt;br /&gt;
  /var/www/matomo/plugins \&lt;br /&gt;
  /var/www/matomo/matomo.php&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier la répartition des propriétaires :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo find /var/www/matomo -xdev -printf &#039;%u:%g\n&#039; \&lt;br /&gt;
  | sort | uniq -c | sort -nr&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identifier les fichiers ou répertoires accessibles en écriture à tous :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo find /var/www/matomo -xdev -perm -0002 \&lt;br /&gt;
  -printf &#039;%m %u:%g %p\n&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette dernière commande ne doit normalement rien retourner.&lt;br /&gt;
&lt;br /&gt;
=== Vérification des répertoires accessibles en écriture ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for DIR in config tmp plugins; do&lt;br /&gt;
  if sudo -u www-data test -w &amp;quot;/var/www/matomo/$DIR&amp;quot;; then&lt;br /&gt;
    echo &amp;quot;$DIR : écriture OK&amp;quot;&lt;br /&gt;
  else&lt;br /&gt;
    echo &amp;quot;$DIR : écriture NON autorisée&amp;quot;&lt;br /&gt;
  fi&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Adapter `www-data` si Matomo utilise un autre compte PHP-FPM.&lt;br /&gt;
&lt;br /&gt;
=== Cas particulier des répertoires ACME ===&lt;br /&gt;
&lt;br /&gt;
Certains répertoires peuvent être créés et administrés par le mécanisme de validation des certificats Let&#039;s Encrypt :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/var/www/matomo/.well-known&lt;br /&gt;
/var/www/matomo/.well-known/acme-challenge&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ils peuvent légitimement appartenir à `root:root` avec des permissions `755`.&lt;br /&gt;
&lt;br /&gt;
Ne pas modifier systématiquement leur propriétaire : vérifier au préalable le mécanisme de validation ACME utilisé sur la VM.&lt;br /&gt;
&lt;br /&gt;
=== Vérification après modification ===&lt;br /&gt;
&lt;br /&gt;
Après toute modification des permissions :&lt;br /&gt;
&lt;br /&gt;
* Vérifier que l&#039;interface Matomo reste accessible.&lt;br /&gt;
* Vérifier que la connexion à MariaDB fonctionne.&lt;br /&gt;
* Vérifier qu&#039;aucune erreur de permission n&#039;apparaît dans les journaux Apache/PHP-FPM.&lt;br /&gt;
* Vérifier que les statistiques continuent à être collectées.&lt;br /&gt;
&lt;br /&gt;
=== Retour d&#039;expérience — AD64, octobre 2026 ===&lt;br /&gt;
&lt;br /&gt;
L&#039;audit de `/var/www/matomo` sur AD64 a donné les résultats suivants :&lt;br /&gt;
&lt;br /&gt;
* 13 315 éléments appartenant à `www-data:www-data`.&lt;br /&gt;
* 2 répertoires appartenant à `root:root` : `.well-known` et `.well-known/acme-challenge`.&lt;br /&gt;
* Répertoires `config`, `tmp` et `plugins` accessibles en écriture à `www-data`.&lt;br /&gt;
* Aucun fichier ou répertoire accessible en écriture à tous.&lt;br /&gt;
* Fichier `config/config.ini.php` initialement en `644` : passage recommandé en `600`.&lt;br /&gt;
* Interface Matomo vérifiée fonctionnelle.&lt;br /&gt;
&lt;br /&gt;
Aucune autre modification des propriétaires ou des permissions n&#039;était nécessaire.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Conclusion :&#039;&#039;&#039; pour les nouvelles installations, appliquer des permissions adaptées dès le départ et réserver l&#039;accès aux fichiers sensibles. Sur les installations existantes, effectuer un audit avant toute modification globale.&lt;br /&gt;
&lt;br /&gt;
== 6. Configuration Apache et HTTPS ==&lt;br /&gt;
&lt;br /&gt;
La configuration du VirtualHost Matomo est décrite dans :&lt;br /&gt;
&lt;br /&gt;
[[Matomo/Apache]]&lt;br /&gt;
&lt;br /&gt;
Deux architectures sont possibles :&lt;br /&gt;
&lt;br /&gt;
* Apache assure directement la terminaison HTTPS.&lt;br /&gt;
* HAProxy assure la terminaison HTTPS et transmet les requêtes à Apache.&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;infrastructure AJLSM utilisant HAProxy, le certificat public est généralement géré sur les répartiteurs de charge.&lt;br /&gt;
&lt;br /&gt;
La procédure de configuration des certificats et des ACL est décrite dans :&lt;br /&gt;
&lt;br /&gt;
[[Matomo/HAProxy]]&lt;br /&gt;
&lt;br /&gt;
Pour une installation utilisant directement Certbot sur Apache :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install certbot python3-certbot-apache&lt;br /&gt;
sudo certbot --apache&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette procédure Certbot ne doit pas être appliquée automatiquement à une VM dont le HTTPS public est déjà géré par HAProxy.&lt;br /&gt;
&lt;br /&gt;
== 7. Initialisation de Matomo ==&lt;br /&gt;
&lt;br /&gt;
Après configuration du VirtualHost, ouvrir dans un navigateur l&#039;URL HTTPS prévue pour Matomo.&lt;br /&gt;
&lt;br /&gt;
L&#039;assistant d&#039;installation permet notamment de :&lt;br /&gt;
&lt;br /&gt;
# Vérifier les prérequis système&lt;br /&gt;
# Configurer la connexion à MariaDB&lt;br /&gt;
# Initialiser les tables Matomo&lt;br /&gt;
# Créer le compte administrateur&lt;br /&gt;
# Déclarer le premier site suivi&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; chaque application suivie doit disposer de son propre identifiant de site Matomo lorsque l&#039;on souhaite séparer ses statistiques.&lt;br /&gt;
&lt;br /&gt;
Exemple : une application Internet et une salle de lecture Drupal peuvent être déclarées comme deux sites distincts.&lt;br /&gt;
&lt;br /&gt;
== 8. Vérifications après installation ==&lt;br /&gt;
&lt;br /&gt;
=== Vérifier la version installée ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /var/www/matomo&lt;br /&gt;
sudo -u www-data php console core:version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Vérifier les services ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl is-active apache2&lt;br /&gt;
systemctl is-active mariadb&lt;br /&gt;
systemctl is-active php8.4-fpm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Adapter la version PHP-FPM si nécessaire.&lt;br /&gt;
&lt;br /&gt;
=== Vérifier les points d&#039;accès ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
MATOMO_URL=&amp;quot;https://matomo.exemple.fr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl -I &amp;quot;$MATOMO_URL/matomo.js&amp;quot;&lt;br /&gt;
curl -I &amp;quot;$MATOMO_URL/matomo.php&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note :&#039;&#039;&#039; selon le comportement du serveur, une requête HEAD peut ne pas produire le même résultat qu&#039;une requête GET. Pour vérifier précisément les codes HTTP :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -sS -o /dev/null -w &amp;quot;HTTP %{http_code}\n&amp;quot; \&lt;br /&gt;
  &amp;quot;$MATOMO_URL/matomo.js&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;installation de Matomo ne garantit pas à elle seule que les applications transmettent leurs visites. Cette vérification relève des chapitres d&#039;intégration.&lt;br /&gt;
&lt;br /&gt;
== 9. Intégration aux applications ==&lt;br /&gt;
&lt;br /&gt;
=== Drupal ===&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Drupal]] pour :&lt;br /&gt;
&lt;br /&gt;
* L&#039;installation du module Drupal Matomo&lt;br /&gt;
* La configuration de l&#039;identifiant du site&lt;br /&gt;
* L&#039;adresse HTTPS du serveur Matomo&lt;br /&gt;
* Les exclusions des pages d&#039;administration&lt;br /&gt;
* Les vérifications de collecte&lt;br /&gt;
&lt;br /&gt;
=== Pleade ===&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Pleade]].&lt;br /&gt;
&lt;br /&gt;
=== Suivi IIIF et événements ===&lt;br /&gt;
&lt;br /&gt;
* [[Matomo/IIIF]]&lt;br /&gt;
* [[Matomo/Evenements]]&lt;br /&gt;
&lt;br /&gt;
== 10. Sécurité et maintenance ==&lt;br /&gt;
&lt;br /&gt;
Après installation, vérifier :&lt;br /&gt;
&lt;br /&gt;
* Que l&#039;interface d&#039;administration Matomo n&#039;est accessible qu&#039;aux utilisateurs ou réseaux autorisés&lt;br /&gt;
* Que les points de collecte nécessaires restent accessibles aux visiteurs&lt;br /&gt;
* Que le certificat HTTPS est valide&lt;br /&gt;
* Que les sauvegardes couvrent la base MariaDB et la configuration Matomo&lt;br /&gt;
* Que les mises à jour de sécurité sont suivies&lt;br /&gt;
&lt;br /&gt;
Voir :&lt;br /&gt;
&lt;br /&gt;
* [[Matomo/HAProxy]]&lt;br /&gt;
* [[Matomo/Maintenance]]&lt;br /&gt;
* [[Matomo/Debug]]&lt;br /&gt;
&lt;br /&gt;
== 11. Installations de référence ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Projet&lt;br /&gt;
! Serveur&lt;br /&gt;
! Domaine Matomo&lt;br /&gt;
! Particularités&lt;br /&gt;
|-&lt;br /&gt;
| AD64&lt;br /&gt;
| ad64&lt;br /&gt;
| ad64-matomo.pleade.com&lt;br /&gt;
| Matomo 5.10.1 ; deux Drupal suivis séparément&lt;br /&gt;
|-&lt;br /&gt;
| APBP2&lt;br /&gt;
| À compléter&lt;br /&gt;
| apbp2-matomo.pleade.com&lt;br /&gt;
| Publication via HAProxy avec restriction de l&#039;administration&lt;br /&gt;
|-&lt;br /&gt;
| MERCURE3&lt;br /&gt;
| À compléter&lt;br /&gt;
| mercure3-matomo.pleade.com&lt;br /&gt;
| Accès restreint à AJLSM&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les paramètres propres à chaque client (domaines, adresses IP, identifiants Matomo, backends HAProxy) ne doivent pas être intégrés directement dans les commandes génériques.&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=Matomo/Installation&amp;diff=6502</id>
		<title>Matomo/Installation</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=Matomo/Installation&amp;diff=6502"/>
		<updated>2026-10-20T10:14:34Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Installation de Matomo sur une VM Ubuntu =&lt;br /&gt;
&lt;br /&gt;
== Objectif ==&lt;br /&gt;
&lt;br /&gt;
Cette procédure décrit l&#039;installation de Matomo sur les VM AJLSM hébergeant les applications Pleade et Drupal.&lt;br /&gt;
&lt;br /&gt;
Elle est destinée à être réutilisée pour les nouveaux projets, indépendamment du client et du nom de domaine.&lt;br /&gt;
&lt;br /&gt;
La configuration Apache, l&#039;intégration Drupal et la publication sécurisée par HAProxy sont détaillées dans des chapitres distincts :&lt;br /&gt;
&lt;br /&gt;
* [[Matomo/Apache]]&lt;br /&gt;
* [[Matomo/Drupal]]&lt;br /&gt;
* [[Matomo/HAProxy]]&lt;br /&gt;
* [[Matomo/Maintenance]]&lt;br /&gt;
&lt;br /&gt;
== 1. Environnement technique ==&lt;br /&gt;
&lt;br /&gt;
=== Versions d&#039;Ubuntu et de PHP ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Ubuntu&lt;br /&gt;
! PHP&lt;br /&gt;
! Statut documentaire&lt;br /&gt;
|-&lt;br /&gt;
| Ubuntu 18.04&lt;br /&gt;
| PHP 8.1 via PHP-FPM&lt;br /&gt;
| Installation historique, hors support standard&lt;br /&gt;
|-&lt;br /&gt;
| Ubuntu 24.04&lt;br /&gt;
| PHP 8.3 via PHP-FPM&lt;br /&gt;
| Installation existante&lt;br /&gt;
|-&lt;br /&gt;
| Ubuntu 26.04&lt;br /&gt;
| PHP 8.4 via PHP-FPM&lt;br /&gt;
| Environnement utilisé pour AD64 en octobre 2026&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; vérifier la compatibilité entre la version de Matomo et celle de PHP avant toute nouvelle installation ou mise à jour.&lt;br /&gt;
&lt;br /&gt;
=== Composants nécessaires ===&lt;br /&gt;
&lt;br /&gt;
* Apache 2.4&lt;br /&gt;
* PHP-FPM&lt;br /&gt;
* MariaDB ou MySQL&lt;br /&gt;
* Extensions PHP requises par Matomo&lt;br /&gt;
* Accès HTTPS, directement ou via HAProxy&lt;br /&gt;
* Accès réseau permettant le téléchargement et les mises à jour de Matomo&lt;br /&gt;
&lt;br /&gt;
== 2. Installation des dépendances PHP ==&lt;br /&gt;
&lt;br /&gt;
Adapter la version de PHP à celle installée sur la VM.&lt;br /&gt;
&lt;br /&gt;
=== Ubuntu 24.04 — PHP 8.3 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install \&lt;br /&gt;
  php8.3-mysql php8.3-gd php8.3-curl php8.3-xml \&lt;br /&gt;
  php8.3-mbstring php8.3-zip php8.3-intl&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ubuntu 26.04 — PHP 8.4 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install \&lt;br /&gt;
  php8.4-mysql php8.4-gd php8.4-curl php8.4-xml \&lt;br /&gt;
  php8.4-mbstring php8.4-zip php8.4-intl&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Vérification ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php -v&lt;br /&gt;
php -m | grep -Ei &#039;mysqli|pdo_mysql|gd|curl|mbstring|xml|zip|intl&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3. Activation de PHP-FPM ==&lt;br /&gt;
&lt;br /&gt;
Exemple pour PHP 8.4 :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install php8.4-fpm&lt;br /&gt;
sudo a2enmod proxy_fcgi setenvif&lt;br /&gt;
sudo a2enconf php8.4-fpm&lt;br /&gt;
sudo systemctl reload apache2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier le service :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl status php8.4-fpm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; sur une VM hébergeant plusieurs applications PHP, vérifier les configurations Apache existantes avant d&#039;activer une configuration PHP-FPM globale.&lt;br /&gt;
&lt;br /&gt;
== 4. Préparation de MariaDB ==&lt;br /&gt;
&lt;br /&gt;
Vérifier que MariaDB est installé et actif :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl status mariadb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Matomo nécessite :&lt;br /&gt;
&lt;br /&gt;
* Une base de données dédiée&lt;br /&gt;
* Un utilisateur SQL dédié&lt;br /&gt;
* Des droits limités à cette base&lt;br /&gt;
&lt;br /&gt;
Exemple générique à adapter :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
CREATE DATABASE matomo&lt;br /&gt;
  CHARACTER SET utf8mb4&lt;br /&gt;
  COLLATE utf8mb4_unicode_ci;&lt;br /&gt;
&lt;br /&gt;
CREATE USER &#039;matomo&#039;@&#039;localhost&#039;&lt;br /&gt;
  IDENTIFIED BY &#039;MOT_DE_PASSE_FORT_A_REMPLACER&#039;;&lt;br /&gt;
&lt;br /&gt;
GRANT ALL PRIVILEGES ON matomo.*&lt;br /&gt;
  TO &#039;matomo&#039;@&#039;localhost&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ne jamais conserver le mot de passe d&#039;exemple dans une installation réelle.&lt;br /&gt;
&lt;br /&gt;
== 5. Installation des fichiers Matomo ==&lt;br /&gt;
&lt;br /&gt;
=== Téléchargement ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /var/www&lt;br /&gt;
&lt;br /&gt;
sudo wget https://builds.matomo.org/matomo.zip&lt;br /&gt;
sudo unzip matomo.zip&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le répertoire de l&#039;application est :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/var/www/matomo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Propriétaire et permissions ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo chown -R www-data:www-data /var/www/matomo&lt;br /&gt;
&lt;br /&gt;
sudo find /var/www/matomo -type d -exec chmod 755 {} \;&lt;br /&gt;
sudo find /var/www/matomo -type f -exec chmod 644 {} \;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ces commandes définissent des permissions de base. Les répertoires nécessitant des écritures par Matomo doivent conserver des droits adaptés à son fonctionnement.&lt;br /&gt;
&lt;br /&gt;
Éviter :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod -R 755 /var/www/matomo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette dernière commande rendrait tous les fichiers exécutables inutilement.&lt;br /&gt;
&lt;br /&gt;
== 6. Configuration Apache et HTTPS ==&lt;br /&gt;
&lt;br /&gt;
La configuration du VirtualHost Matomo est décrite dans :&lt;br /&gt;
&lt;br /&gt;
[[Matomo/Apache]]&lt;br /&gt;
&lt;br /&gt;
Deux architectures sont possibles :&lt;br /&gt;
&lt;br /&gt;
* Apache assure directement la terminaison HTTPS.&lt;br /&gt;
* HAProxy assure la terminaison HTTPS et transmet les requêtes à Apache.&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;infrastructure AJLSM utilisant HAProxy, le certificat public est généralement géré sur les répartiteurs de charge.&lt;br /&gt;
&lt;br /&gt;
La procédure de configuration des certificats et des ACL est décrite dans :&lt;br /&gt;
&lt;br /&gt;
[[Matomo/HAProxy]]&lt;br /&gt;
&lt;br /&gt;
Pour une installation utilisant directement Certbot sur Apache :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt install certbot python3-certbot-apache&lt;br /&gt;
sudo certbot --apache&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette procédure Certbot ne doit pas être appliquée automatiquement à une VM dont le HTTPS public est déjà géré par HAProxy.&lt;br /&gt;
&lt;br /&gt;
== 7. Initialisation de Matomo ==&lt;br /&gt;
&lt;br /&gt;
Après configuration du VirtualHost, ouvrir dans un navigateur l&#039;URL HTTPS prévue pour Matomo.&lt;br /&gt;
&lt;br /&gt;
L&#039;assistant d&#039;installation permet notamment de :&lt;br /&gt;
&lt;br /&gt;
# Vérifier les prérequis système&lt;br /&gt;
# Configurer la connexion à MariaDB&lt;br /&gt;
# Initialiser les tables Matomo&lt;br /&gt;
# Créer le compte administrateur&lt;br /&gt;
# Déclarer le premier site suivi&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; chaque application suivie doit disposer de son propre identifiant de site Matomo lorsque l&#039;on souhaite séparer ses statistiques.&lt;br /&gt;
&lt;br /&gt;
Exemple : une application Internet et une salle de lecture Drupal peuvent être déclarées comme deux sites distincts.&lt;br /&gt;
&lt;br /&gt;
== 8. Vérifications après installation ==&lt;br /&gt;
&lt;br /&gt;
=== Vérifier la version installée ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /var/www/matomo&lt;br /&gt;
sudo -u www-data php console core:version&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Vérifier les services ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl is-active apache2&lt;br /&gt;
systemctl is-active mariadb&lt;br /&gt;
systemctl is-active php8.4-fpm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Adapter la version PHP-FPM si nécessaire.&lt;br /&gt;
&lt;br /&gt;
=== Vérifier les points d&#039;accès ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
MATOMO_URL=&amp;quot;https://matomo.exemple.fr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl -I &amp;quot;$MATOMO_URL/matomo.js&amp;quot;&lt;br /&gt;
curl -I &amp;quot;$MATOMO_URL/matomo.php&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note :&#039;&#039;&#039; selon le comportement du serveur, une requête HEAD peut ne pas produire le même résultat qu&#039;une requête GET. Pour vérifier précisément les codes HTTP :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
curl -sS -o /dev/null -w &amp;quot;HTTP %{http_code}\n&amp;quot; \&lt;br /&gt;
  &amp;quot;$MATOMO_URL/matomo.js&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;installation de Matomo ne garantit pas à elle seule que les applications transmettent leurs visites. Cette vérification relève des chapitres d&#039;intégration.&lt;br /&gt;
&lt;br /&gt;
== 9. Intégration aux applications ==&lt;br /&gt;
&lt;br /&gt;
=== Drupal ===&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Drupal]] pour :&lt;br /&gt;
&lt;br /&gt;
* L&#039;installation du module Drupal Matomo&lt;br /&gt;
* La configuration de l&#039;identifiant du site&lt;br /&gt;
* L&#039;adresse HTTPS du serveur Matomo&lt;br /&gt;
* Les exclusions des pages d&#039;administration&lt;br /&gt;
* Les vérifications de collecte&lt;br /&gt;
&lt;br /&gt;
=== Pleade ===&lt;br /&gt;
&lt;br /&gt;
Voir [[Matomo/Pleade]].&lt;br /&gt;
&lt;br /&gt;
=== Suivi IIIF et événements ===&lt;br /&gt;
&lt;br /&gt;
* [[Matomo/IIIF]]&lt;br /&gt;
* [[Matomo/Evenements]]&lt;br /&gt;
&lt;br /&gt;
== 10. Sécurité et maintenance ==&lt;br /&gt;
&lt;br /&gt;
Après installation, vérifier :&lt;br /&gt;
&lt;br /&gt;
* Que l&#039;interface d&#039;administration Matomo n&#039;est accessible qu&#039;aux utilisateurs ou réseaux autorisés&lt;br /&gt;
* Que les points de collecte nécessaires restent accessibles aux visiteurs&lt;br /&gt;
* Que le certificat HTTPS est valide&lt;br /&gt;
* Que les sauvegardes couvrent la base MariaDB et la configuration Matomo&lt;br /&gt;
* Que les mises à jour de sécurité sont suivies&lt;br /&gt;
&lt;br /&gt;
Voir :&lt;br /&gt;
&lt;br /&gt;
* [[Matomo/HAProxy]]&lt;br /&gt;
* [[Matomo/Maintenance]]&lt;br /&gt;
* [[Matomo/Debug]]&lt;br /&gt;
&lt;br /&gt;
== 11. Installations de référence ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Projet&lt;br /&gt;
! Serveur&lt;br /&gt;
! Domaine Matomo&lt;br /&gt;
! Particularités&lt;br /&gt;
|-&lt;br /&gt;
| AD64&lt;br /&gt;
| ad64&lt;br /&gt;
| ad64-matomo.pleade.com&lt;br /&gt;
| Matomo 5.10.1 ; deux Drupal suivis séparément&lt;br /&gt;
|-&lt;br /&gt;
| APBP2&lt;br /&gt;
| À compléter&lt;br /&gt;
| apbp2-matomo.pleade.com&lt;br /&gt;
| Publication via HAProxy avec restriction de l&#039;administration&lt;br /&gt;
|-&lt;br /&gt;
| MERCURE3&lt;br /&gt;
| À compléter&lt;br /&gt;
| mercure3-matomo.pleade.com&lt;br /&gt;
| Accès restreint à AJLSM&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les paramètres propres à chaque client (domaines, adresses IP, identifiants Matomo, backends HAProxy) ne doivent pas être intégrés directement dans les commandes génériques.&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=AJLSM-DEPLOY_%E2%80%94_Version_1.0.2&amp;diff=6501</id>
		<title>AJLSM-DEPLOY — Version 1.0.2</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=AJLSM-DEPLOY_%E2%80%94_Version_1.0.2&amp;diff=6501"/>
		<updated>2026-10-19T07:36:46Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : Page créée avec « = AJLSM-DEPLOY — Version 1.0.2 =  Mise à jour : 19 octobre 2026. Ce guide décrit les scripts du dossier &amp;#039;&amp;#039;&amp;#039;ajlsm-deploy-v1.0.2&amp;#039;&amp;#039;&amp;#039;, à installer dans &amp;#039;&amp;#039;&amp;#039;/opt/ajlsm-depl... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= AJLSM-DEPLOY — Version 1.0.2 =&lt;br /&gt;
&lt;br /&gt;
Mise à jour : 19 octobre 2026. Ce guide décrit les scripts du dossier&lt;br /&gt;
&#039;&#039;&#039;ajlsm-deploy-v1.0.2&#039;&#039;&#039;, à installer dans &#039;&#039;&#039;/opt/ajlsm-deploy/v1&#039;&#039;&#039;.&lt;br /&gt;
Ce chemin est le répertoire définitif de lancement sur le nœud Proxmox ;&lt;br /&gt;
les anciennes copies de /usr/local/sbin ne sont pas remplacées implicitement.&lt;br /&gt;
Les lots NFS, Apache et Matomo précédents sont historiques. Garder scripts,&lt;br /&gt;
modules et modèles du même lot. Rotation des logs et update.sh hors périmètre.&lt;br /&gt;
&lt;br /&gt;
== Périmètre et architecture ==&lt;br /&gt;
&lt;br /&gt;
Les scripts tournent sur le nœud Proxmox. Ils configurent le clone depuis un&lt;br /&gt;
projet YAML strict, utilisent QEMU Guest Agent pour les opérations invitées,&lt;br /&gt;
et SSH pour certaines vérifications/postconfigurations. Le moteur principal&lt;br /&gt;
orchestre les phases ; les modules spécialisés traitent racine, postconfiguration,&lt;br /&gt;
NFS, Apache, SQL Matomo, activation Matomo et inventaire des tâches planifiées.&lt;br /&gt;
Les helpers communs valident le YAML et affichent les commandes suivantes.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ce n&#039;est pas un gestionnaire complet de l&#039;infrastructure externe.&#039;&#039;&#039; DNS,&lt;br /&gt;
OPNsense, Ansible, autorisation Eole3 et certificats publics ont leurs procédures.&lt;br /&gt;
Le script ne détruit pas la VM existante et ne modifie pas TEMPLATE3.&lt;br /&gt;
&lt;br /&gt;
== Répertoire définitif et exemple MERCURE3 ==&lt;br /&gt;
&lt;br /&gt;
Les cinq programmes affichent la version 1.0.2 avec --version.&lt;br /&gt;
Leur --help rappelle le même répertoire et le même exemple que cette page.&lt;br /&gt;
Ces valeurs sont centralisées dans ajlsm_deploy_version.py.&lt;br /&gt;
Les suggestions visent les programmes du dossier réellement exécuté :&lt;br /&gt;
utiliser le lot installé ci-dessous, pas un ancien dossier de recette.&lt;br /&gt;
&lt;br /&gt;
Sur Saturne3, après installation du lot complet selon INSTALLATION-V1.txt :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /opt/ajlsm-deploy/v1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Toutes les commandes ./ de cette page se lancent depuis ce répertoire.&lt;br /&gt;
Depuis un autre répertoire du même nœud, utiliser le chemin absolu du&lt;br /&gt;
programme sous /opt/ajlsm-deploy/v1 et celui du YAML.&lt;br /&gt;
Les YAML opérationnels restent sous /etc/ajlsm/deploy/projets/,&lt;br /&gt;
les journaux sous /var/lib/ajlsm-deploy/cycles/. Les archives/recettes&lt;br /&gt;
sous /root/ajlsm-deploy ne sont plus le répertoire de lancement v1.&lt;br /&gt;
Ne pas mélanger les modules ou changer de lot pendant un cycle.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;exemples/mercure3-exemple.yaml&#039;&#039;&#039; est un exemple renseigné avec les IP&lt;br /&gt;
réelles de MERCURE3, pas une préconfiguration générique.&lt;br /&gt;
Les commandes MERCURE3 de ce guide sont des exemples à adapter au projet.&lt;br /&gt;
Le nom de la VM, ses DNS et ses fichiers YAML opérationnels existants ne sont&lt;br /&gt;
pas renommés. En particulier, conserver le chemin du YAML pour la reprise :&lt;br /&gt;
le journal est indexé par ce chemin absolu.&lt;br /&gt;
modeles/projet-vierge.yaml demeure le modèle générique sans valeurs.&lt;br /&gt;
&lt;br /&gt;
== Prérequis impératif : OS de TEMPLATE3 à jour ==&lt;br /&gt;
&lt;br /&gt;
Avant TOUT nouveau clonage, maintenir l’OS Ubuntu de TEMPLATE3 à jour.&lt;br /&gt;
La VM clonée hérite de cet état. Maintenance manuelle distincte : les scripts&lt;br /&gt;
de déploiement ne mettent pas le modèle à jour. Prévoir une sauvegarde&lt;br /&gt;
récupérable et une fenêtre sans conflit d’IP avec les clones existants.&lt;br /&gt;
Ne pas démarrer ni convertir à l’aveugle un modèle marqué template Proxmox.&lt;br /&gt;
&lt;br /&gt;
Dans la console de TEMPLATE3, après vérification de son identité :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
hostname -f&lt;br /&gt;
cat /etc/os-release&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt upgrade&lt;br /&gt;
apt list --upgradable&lt;br /&gt;
if [ -f /var/run/reboot-required ]; then&lt;br /&gt;
  cat /var/run/reboot-required&lt;br /&gt;
  cat /var/run/reboot-required.pkgs 2&amp;gt;/dev/null || true&lt;br /&gt;
fi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Examiner toutes les erreurs, messages APT et paquets retenus/différés.&lt;br /&gt;
apt update seul ne met pas les paquets à jour. Pas de -y, full-upgrade,&lt;br /&gt;
do-release-upgrade ou update.sh automatique. Si un redémarrage est demandé :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo reboot&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Attendre le retour du modèle, puis dans sa console :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
hostname -f&lt;br /&gt;
uname -r&lt;br /&gt;
systemctl --failed&lt;br /&gt;
apt list --upgradable&lt;br /&gt;
test ! -f /var/run/reboot-required&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Examiner les résultats, noter date/OS/noyau dans le registre de maintenance.&lt;br /&gt;
Après validation, arrêter proprement TEMPLATE3 :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo shutdown -h now&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puis sur Saturne3 :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
qm status 506&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
506 correspond au template_vmid de cette recette : vérifier la valeur du YAML.&lt;br /&gt;
Le modèle doit être arrêté avant le clonage. Ni le lanceur ni les précontrôles&lt;br /&gt;
ne certifient automatiquement sa fraîcheur APT. Cette maintenance n’a pas&lt;br /&gt;
été réalisée par les scripts livrés. Saturne3 et HAProxy ont leur maintenance&lt;br /&gt;
distincte, non demandée ici.&lt;br /&gt;
Voir PREREQUIS-OS-ET-PUBLICATION.txt et les documentations Ubuntu :&lt;br /&gt;
[https://ubuntu.com/server/docs/how-to/software/package-management/ Gestion des paquets]&lt;br /&gt;
et [https://ubuntu.com/server/docs/how-to/software/automatic-updates/ Mises à jour automatiques].&lt;br /&gt;
&lt;br /&gt;
== Paramètres prévus avant la création ==&lt;br /&gt;
&lt;br /&gt;
* Identité projet, environnement et tags : interne, client, prod ; types YAML stricts.&lt;br /&gt;
* Ressources, template, stockage, IP privées/VPN/publique, passerelle et DNS.&lt;br /&gt;
* Domaines principal, préprod et Matomo définitifs, sans https:// ni chemin.&lt;br /&gt;
* NFS existant et droits accordés par l&#039;administrateur du serveur.&lt;br /&gt;
* Activation des vhosts distincte de l&#039;installation des logiciels.&lt;br /&gt;
* Noms SQL dédiés Matomo, sans secret dans le YAML.&lt;br /&gt;
&lt;br /&gt;
Référence MERCURE3 : hostname mercure3.ajlsm.com, VPN 10.0.0.43,&lt;br /&gt;
réseau données 192.168.123.27, publique 51.83.117.113. Matomo :&lt;br /&gt;
mercure3-matomo.pleade.com ; préprod : mercure3-preprod.pleade.com.&lt;br /&gt;
Ne pas conserver deux VM avec ces mêmes adresses.&lt;br /&gt;
&lt;br /&gt;
Chez OVH, principal A vers 51.83.117.113, domaines secondaires CNAME vers&lt;br /&gt;
mercure3.ajlsm.com dans la recette. Ne pas publier d&#039;AAAA sans IPv6 opérationnel.&lt;br /&gt;
Pour un domaine secondaire sur la même IP, réutiliser la VIP/NAT existante si&lt;br /&gt;
elle et le filtrage traitent déjà le flux requis ; ne pas dupliquer OPNsense.&lt;br /&gt;
Le trafic public passe par la VIP HAProxy 10.0.0.32, nœuds .30 et .31.&lt;br /&gt;
&lt;br /&gt;
== Préconfiguration et contrôle ==&lt;br /&gt;
&lt;br /&gt;
modeles/projet-vierge.yaml contient des null, jamais une liste [à renseigner].&lt;br /&gt;
null est valide pour proxmox.vmid automatique, pas pour un champ obligatoire.&lt;br /&gt;
Les sections métier peuvent être omises, mais doivent être complètes si présentes.&lt;br /&gt;
exemples/mercure3-exemple.yaml prépare une recréation volontaire, pas une VM parallèle.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml ./modeles/projet-vierge.yaml --with-metier --output /etc/ajlsm/deploy/projets/mercure3-initial.yaml&lt;br /&gt;
./ajlsm-deploy-yaml /etc/ajlsm/deploy/projets/mercure3-initial.yaml --check&lt;br /&gt;
./ajlsm-deploy-cycle /etc/ajlsm/deploy/projets/mercure3-initial.yaml --plan&lt;br /&gt;
./ajlsm-deploy-check /etc/ajlsm/deploy/projets/mercure3-initial.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le parcours complet de l&#039;assistant est désormais &#039;&#039;&#039;--with-metier&#039;&#039;&#039; :&lt;br /&gt;
NFS, domaines Matomo/Apache et SQL dédiés dans le même YAML initial.&lt;br /&gt;
Sans modèle, utiliser --new --with-metier avec un chemin inexistant.&lt;br /&gt;
Les valeurs valides existantes sont conservées ; --review les revoit aussi.&lt;br /&gt;
Le guide détaillé GUIDE-YAML.txt décrit les questions et les activations :&lt;br /&gt;
Drupal seulement si vérifié, Pleade préprod désactivé en son absence,&lt;br /&gt;
Matomo Apache false jusqu&#039;à publication-matomo après pause externe.&lt;br /&gt;
Le mode --with-matomo-site reste une activation MANUELLE distincte,&lt;br /&gt;
incompatible avec --with-metier ; inutile au cycle guidé actuel.&lt;br /&gt;
OS du modèle, DNS, OPNsense, ACME sur les deux HAProxy, Ansible/whitelist&lt;br /&gt;
et autorisation NFS sont rappelés mais pas vérifiés ni enregistrés comme tels.&lt;br /&gt;
&lt;br /&gt;
Les options individuelles restent disponibles : --with-nfs, --with-matomo, --with-apache et&lt;br /&gt;
--with-matomo-sql ; --review revoit aussi les valeurs valides. --new crée un&lt;br /&gt;
nouveau chemin. Les fichiers existants ne sont pas écrasés. --check et&lt;br /&gt;
--yaml-only sont des contrôles locaux, pas une vérification d&#039;infrastructure.&lt;br /&gt;
Prévoir apache.matomo.activer=false pour le cycle initial ; un projet&lt;br /&gt;
d&#039;activation true est refusé par le cycle avant toute phase passant par Apache.&lt;br /&gt;
&lt;br /&gt;
== Cycle initial : dix-sept étapes ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Étape !! Simulation / lecture !! Exécution&lt;br /&gt;
|-&lt;br /&gt;
| clonage || --dry-run || --clone&lt;br /&gt;
|-&lt;br /&gt;
| ressources || --resources-dry-run || --configure-resources&lt;br /&gt;
|-&lt;br /&gt;
| premier-demarrage || --first-boot-dry-run || --first-boot-apply&lt;br /&gt;
|-&lt;br /&gt;
| extension-racine || --root-grow-dry-run || --root-grow-apply&lt;br /&gt;
|-&lt;br /&gt;
| identite || --system-dry-run || --system-apply&lt;br /&gt;
|-&lt;br /&gt;
| netplan || --network-dry-run || --network-apply&lt;br /&gt;
|-&lt;br /&gt;
| activation-reseau || --network-enable-dry-run || --network-enable&lt;br /&gt;
|-&lt;br /&gt;
| audit-ssh || --ssh-audit || audit, pas de simulation distincte&lt;br /&gt;
|-&lt;br /&gt;
| securisation-ssh || aucune || --ssh-secure&lt;br /&gt;
|-&lt;br /&gt;
| mot-de-passe || aucune || --password-ajlsm&lt;br /&gt;
|-&lt;br /&gt;
| tls || aucune || --tls-apply&lt;br /&gt;
|-&lt;br /&gt;
| nfs || --nfs-dry-run puis --nfs-check || --nfs-apply&lt;br /&gt;
|-&lt;br /&gt;
| apache || --apache-dry-run || --apache-apply&lt;br /&gt;
|-&lt;br /&gt;
| matomo-sql || --matomo-sql-dry-run || --matomo-sql-prepare&lt;br /&gt;
|-&lt;br /&gt;
| tomcat-cron || --scheduled-dry-run || --scheduled-apply&lt;br /&gt;
|-&lt;br /&gt;
| taches-planifiees || --scheduled-audit || aucune modification&lt;br /&gt;
|-&lt;br /&gt;
| publication-matomo || --matomo-guided-dry-run || --matomo-guided&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le clone est isolé avant premier démarrage. L&#039;extension racine suit le premier&lt;br /&gt;
démarrage et ne doit pas être confondue avec le disque virtuel déjà agrandi.&lt;br /&gt;
Puis identité, réseau, SSH, mot de passe et certificat interne sont traités.&lt;br /&gt;
Les phases métier non demandées sont ignorées explicitement.&lt;br /&gt;
&lt;br /&gt;
=== Attente réseau pendant l&#039;isolation ===&lt;br /&gt;
&lt;br /&gt;
Le journal MERCURE3 transmis montre wait-online en attente 120 secondes avant&lt;br /&gt;
activation des carriers ; le réseau est ensuite online sur les deux cartes.&lt;br /&gt;
Le lot ajoute une dispense conditionnelle liée à l&#039;UUID pendant l&#039;isolation,&lt;br /&gt;
dès que QGA est disponible. Les phases first-boot et system l&#039;installent après&lt;br /&gt;
les confirmations et gardes ; network-enable la retire après ses contrôles&lt;br /&gt;
puis vérifie le fonctionnement normal de wait-online avant onboot.&lt;br /&gt;
Le repli réseau remet la dispense après réisolation. Pas de mask/disable,&lt;br /&gt;
pas de changement Netplan optional ou de TEMPLATE3. Les simulations n&#039;écrivent&lt;br /&gt;
aucun fichier. Ce correctif reste à recetter sur un clone ; il ne nécessite&lt;br /&gt;
pas de reconstruire la VM actuelle pour continuer les étapes métier.&lt;br /&gt;
Voir CORRECTIF-WAIT-ONLINE.txt pour les deux fichiers gérés, limites et reprise.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /etc/ajlsm/deploy/projets/mercure3-initial.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les confirmations OUI/NON, défaut NON, et saisies natives restent interactives.&lt;br /&gt;
Pas d&#039;arrêt entre commandes réussies ; arrêt au premier refus ou erreur.&lt;br /&gt;
--agent-timeout est transmis aux phases, défaut 300 secondes, pas un timeout global.&lt;br /&gt;
Après diagnostic, --from reprend l&#039;étape incluse sans refaire les précédentes.&lt;br /&gt;
Un --plan n&#039;exécute rien mais ne garantit ni Proxmox ni l&#039;infrastructure externe.&lt;br /&gt;
&lt;br /&gt;
== NFS : autorisation manuelle guidée ==&lt;br /&gt;
&lt;br /&gt;
Dépôt d&#039;exemples : 192.168.123.202:/var/data/pleade.com-data/data,&lt;br /&gt;
point local identique, mode ro. Un autre dépôt est paramétrable ; plusieurs&lt;br /&gt;
dépôts de MERCURE3 restent une exception manuelle. Le script affiche le fichier&lt;br /&gt;
exports et la ligne à adapter sur Eole3, sans s&#039;y connecter en administrateur.&lt;br /&gt;
L&#039;autorisation de 192.168.123.27 en ro a été réalisée dans la recette.&lt;br /&gt;
Les autres exports et données doivent être conservés. Pas de chmod/chown récursif.&lt;br /&gt;
&lt;br /&gt;
== Apache, Drupal et Pleade ==&lt;br /&gt;
&lt;br /&gt;
Six fichiers gérés sous /etc/apache2/sites-available : HTTP et TLS pour Drupal,&lt;br /&gt;
préprod et Matomo ; fichier robots préprod séparé. Activation par symlinks selon&lt;br /&gt;
le YAML, manifeste, sauvegarde, syntaxe candidate et reload avec tentative de&lt;br /&gt;
restauration locale sur erreur. Une interruption brutale demande un diagnostic.&lt;br /&gt;
Un vhost préparé n&#039;installe pas un logiciel et ne valide pas une application.&lt;br /&gt;
Les fichiers gérés modifiés hors déploiement provoquent un refus, pas un écrasement.&lt;br /&gt;
&lt;br /&gt;
Drupal hérité a été vérifié utilisable avec MariaDB et drupal_template ; son&lt;br /&gt;
vhost principal est actif dans la recette. Pas de personnalisation SQL Drupal&lt;br /&gt;
dédiée dans ce lot. Pleade n&#039;est pas installé, sa préprod reste désactivée ;&lt;br /&gt;
pas d&#039;appel à update.sh. Les futurs slecture et internet ne sont pas publiés.&lt;br /&gt;
&lt;br /&gt;
== Matomo : préparation SQL puis activation coordonnée ==&lt;br /&gt;
&lt;br /&gt;
Base et compte locaux dédiés : matomo_mercure3, sans adoption de matomo_template.&lt;br /&gt;
Configuration préparée root privée dans /var/lib/ajlsm-matomo-sql ; ne pas&lt;br /&gt;
transmettre ces fichiers. En fin de cycle, publication-matomo affiche la pause&lt;br /&gt;
externe, demande une attestation OUI/NON puis active Matomo avec le MÊME YAML.&lt;br /&gt;
Il passe activer=true en mémoire uniquement ; le YAML initial reste intact.&lt;br /&gt;
En mode manuel, après SQL :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3-initial.yaml --matomo-guided-dry-run&lt;br /&gt;
./ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3-initial.yaml --matomo-guided&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L’activation coordonnée conserve Drupal/Pleade. Le mode historique reste&lt;br /&gt;
possible : --with-matomo-site crée une copie d’activation, ensuite utilisée par&lt;br /&gt;
--matomo-site-dry-run puis --matomo-site-apply.&lt;br /&gt;
Ne pas utiliser --apache-apply seul pour cette transition et ne pas relancer&lt;br /&gt;
le clonage avec la copie d&#039;activation. Le module désactive les anciens vhosts&lt;br /&gt;
Matomo connus, sauvegarde le cache, installe la configuration privée et active&lt;br /&gt;
le projet avec contrôle HTTPS local. Les sauvegardes peuvent contenir des secrets.&lt;br /&gt;
&lt;br /&gt;
== Certificats en prérequis et pause avant activation ==&lt;br /&gt;
&lt;br /&gt;
Recommandation : DNS puis challenge ACME stateless prêts, émettre/déployer les&lt;br /&gt;
certificats publics en prérequis, avant même le clonage backend. Le challenge&lt;br /&gt;
HAProxy ne dépend pas de Matomo. Une pause reste obligatoire à publication-matomo&lt;br /&gt;
pour vérifier les certificats et le routage restreint sur LES DEUX nœuds.&lt;br /&gt;
NON arrête proprement le cycle ; --resume reprend après préparation externe.&lt;br /&gt;
Aucune commande ACME/Ansible n’est exécutée par le script et l’attestation&lt;br /&gt;
humaine ne constitue pas une vérification automatisée.&lt;br /&gt;
&lt;br /&gt;
Le certificat interne généré dans le clone n&#039;est pas le certificat public.&lt;br /&gt;
Les certificats publics sont vérifiés/générés avec acme.sh sous l&#039;utilisateur&lt;br /&gt;
acme sur les deux HAProxy, l&#039;un après l&#039;autre. Connexion hpr puis sudo -i,&lt;br /&gt;
pas root SSH. Conserver le challenge HTTP-01 stateless avant la whitelist.&lt;br /&gt;
Émission et déploiement Matomo ont réussi sur les deux nœuds lors de la recette.&lt;br /&gt;
Un certificat valide pour le même domaine n&#039;est pas à refaire parce que le&lt;br /&gt;
backend est recréé ; revérifier validité, déploiement et renouvellement.&lt;br /&gt;
&lt;br /&gt;
Ansible ajoute ACL du domaine, refus hors whitelist, redirection HTTPS et&lt;br /&gt;
backend SNI vers 10.0.0.43:443. Matomo interne MERCURE3 : allowed_ajlsm uniquement.&lt;br /&gt;
Pour un client, prévoir AJLSM et whitelist client selon les règles préprod.&lt;br /&gt;
Le backend conserve ssl verify none : l&#039;identité du backend n&#039;est pas validée.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml --syntax-check&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml --limit haproxy01.ajlsm.lan --check --diff&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml --limit haproxy02.ajlsm.lan --check --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Examiner tous les diffs puis appliquer séparément en retirant --check, attendre&lt;br /&gt;
le succès du premier nœud avant le second. Aucun lancement Ansible automatique&lt;br /&gt;
depuis Proxmox. Le check-mode n&#039;est pas l&#039;application réelle.&lt;br /&gt;
Recette transmise : deux applications réussies, validation et restart signalés,&lt;br /&gt;
aucun failed/unreachable. Avertissement Python découvert /usr/bin/python3.10,&lt;br /&gt;
non bloquant dans ces exécutions. Aucun changement d&#039;interpréteur ici.&lt;br /&gt;
&lt;br /&gt;
Tester HTTPS sans -k depuis l&#039;IP autorisée puis hors whitelist. Résultats&lt;br /&gt;
transmis : 200 avec en-tête Matomo via VPN bureau, 403 hors whitelist.&lt;br /&gt;
Un HTTP 200 n&#039;est pas une validation d&#039;installation fonctionnelle.&lt;br /&gt;
&lt;br /&gt;
== Tâches planifiées : correction ciblée puis audit ==&lt;br /&gt;
&lt;br /&gt;
--scheduled-audit inventorie crontabs root/ajlsm/www-data, fichiers système,&lt;br /&gt;
noms des scripts périodiques, timers systemd et instances Tomcat. Les commandes&lt;br /&gt;
et arguments privés ne sont pas affichés. L&#039;audit historique et l&#039;inventaire&lt;br /&gt;
avant traitement confirment 13 lignes Tomcat et trois processus, sans Pleade détecté.&lt;br /&gt;
Après cycle du 18 octobre : zéro tâche Tomcat active pour les trois instances&lt;br /&gt;
vides ; processus déjà lancés conservés et archivage mensuel inchangé.&lt;br /&gt;
Les tâches des autres comptes, timers utilisateurs et contenus des scripts&lt;br /&gt;
restent hors audit. L&#039;inventaire seul n&#039;effectue aucune désactivation.&lt;br /&gt;
Code 0 = inventaire obtenu, pas tâches approuvées. Rotation des logs inchangée.&lt;br /&gt;
&lt;br /&gt;
La phase &#039;&#039;&#039;tomcat-cron&#039;&#039;&#039; a été autorisée pour ne pas reproduire ces tâches&lt;br /&gt;
inutiles sur les nouveaux clones. --scheduled-dry-run affiche les lignes&lt;br /&gt;
reconnues à commenter ; --scheduled-apply demande OUI/NON, sauvegarde la crontab&lt;br /&gt;
ajlsm et commente ces seules lignes avec un marqueur réversible. Elle ne lance&lt;br /&gt;
aucune commande de démarrage, arrêt ou nettoyage Tomcat. Le cycle l&#039;exécute en&lt;br /&gt;
étape 15, puis audite le résultat en étape 16.&lt;br /&gt;
&lt;br /&gt;
Critères conservateurs : répertoire Pleade présent et entièrement vide,&lt;br /&gt;
webapps absent d&#039;autre application et lien pleade vers le chemin attendu,&lt;br /&gt;
pas de contexte externe dans conf/Catalina/localhost. Une implantation non&lt;br /&gt;
vérifiable ou un contenu partiel conserve les tâches. Une commande inconnue&lt;br /&gt;
visant une instance vide bloque la phase, sans modification partielle.&lt;br /&gt;
Seules les formes exactes des commandes héritées auditées sont reconnues.&lt;br /&gt;
&lt;br /&gt;
Sauvegarde privée : /var/backups/ajlsm-scheduled/transaction-* ; journal :&lt;br /&gt;
/var/lib/ajlsm-scheduled/transaction.json. Vérification identité/UUID et&lt;br /&gt;
empreinte de la crontab avant application, relecture après installation.&lt;br /&gt;
Restauration tentée sur erreur contrôlée si elle n&#039;écrase pas un changement&lt;br /&gt;
concurrent détecté. Sinon journal conservé et reprise bloquée pour examen manuel.&lt;br /&gt;
Le verrou ne protège pas contre crontab -e dans un autre terminal : ne pas&lt;br /&gt;
modifier simultanément les tâches ou déployer une application pendant la phase.&lt;br /&gt;
L&#039;interface crontab ne fournit pas de comparaison-installation atomique face&lt;br /&gt;
aux outils extérieurs. Les @reboot des premiers démarrages du clone peuvent&lt;br /&gt;
déjà avoir lancé Tomcat : seuls les lancements futurs sont neutralisés.&lt;br /&gt;
Pas de réactivation automatique lors d&#039;une installation Pleade ultérieure.&lt;br /&gt;
&lt;br /&gt;
== Finalisation fonctionnelle, hors déploiement piloté ==&lt;br /&gt;
&lt;br /&gt;
L&#039;installateur Matomo a confirmé « Tables créées » dans la recette. Création&lt;br /&gt;
du superadministrateur, premier site, fin de l&#039;assistant et intégration du suivi&lt;br /&gt;
restent manuelles. Ne pas laisser un installateur inachevé ouvert durablement.&lt;br /&gt;
Lire FINALISATION-MATOMO.txt : reprise directe tablesCreation et avertissement&lt;br /&gt;
sur systemCheck qui supprime la configuration locale préparée en version auditée.&lt;br /&gt;
Diagnostics applicatifs non annoncés comme faits. Ne pas partager de secrets.&lt;br /&gt;
&lt;br /&gt;
== Point d’arrêt et reprise depuis tout répertoire ==&lt;br /&gt;
&lt;br /&gt;
Le nouveau lanceur conserve un journal privé sur Saturne3 dans&lt;br /&gt;
/var/lib/ajlsm-deploy/cycles/, mode 600, historique par exécution.&lt;br /&gt;
Il n’enregistre ni mots de passe, ni sortie complète des phases.&lt;br /&gt;
Il suit étape courante, dernière réussite, dates UTC, codes de sortie,&lt;br /&gt;
empreintes du YAML/lot, hôte et identité VMID/UUID de la cible.&lt;br /&gt;
Un verrou protège ce journal, pas les interventions d’un autre administrateur.&lt;br /&gt;
&lt;br /&gt;
Avec chemins absolus, depuis n’importe quel répertoire &#039;&#039;&#039;du même nœud&#039;&#039;&#039; :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/ajlsm-deploy/v1/ajlsm-deploy-cycle /etc/ajlsm/deploy/projets/mercure3-initial.yaml --status&lt;br /&gt;
/opt/ajlsm-deploy/v1/ajlsm-deploy-cycle /etc/ajlsm/deploy/projets/mercure3-initial.yaml --resume&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--status ne contacte pas Proxmox et ne crée aucun journal. --resume reprend&lt;br /&gt;
la première étape non réussie, avec contrôles et confirmations habituels.&lt;br /&gt;
Une faute « ouii » à tls se reprend donc à tls sans reclonage.&lt;br /&gt;
La reprise refuse les changements de nœud, YAML, code/ordre ou d’identité&lt;br /&gt;
VM enregistrée. Elle ne relance pas un cycle déjà terminé.&lt;br /&gt;
Après coupure brutale, en_cours signifie résultat inconnu : examiner les&lt;br /&gt;
journaux transactionnels, l’état et les processus avant reprise.&lt;br /&gt;
Le journal n’est pas une preuve de conformité permanente de l’infrastructure.&lt;br /&gt;
&lt;br /&gt;
--from étape reste une reprise explicite après diagnostic, qui démarre un&lt;br /&gt;
nouveau journal et marque les étapes antérieures ignorées, pas vérifiées.&lt;br /&gt;
Ne pas effacer les journaux pour contourner une erreur.&lt;br /&gt;
Les anciens lots sans journal ne permettent pas --resume rétroactif :&lt;br /&gt;
consulter leur sortie console puis reprendre avec --from.&lt;br /&gt;
Pour la VM actuelle, l’application de la dernière simulation Matomo n’est&lt;br /&gt;
pas confirmée. Contrôler avant de reprendre à publication-matomo, sans clonage.&lt;br /&gt;
&lt;br /&gt;
== Détails de sécurité conservés de la documentation du 16 octobre ==&lt;br /&gt;
&lt;br /&gt;
L’audit SSH lit la clé ED25519 via QEMU, vérifie son format binaire, puis&lt;br /&gt;
compare indépendamment celle exposée par ssh-keyscan. Une divergence refuse&lt;br /&gt;
la suite. Après concordance seulement, sauvegarde et remplacement atomique&lt;br /&gt;
possible de /root/.ssh/known_hosts sur Saturne3 ; les autres hôtes sont conservés,&lt;br /&gt;
y compris traitement ciblé des anciennes entrées hachées de l’IP du clone.&lt;br /&gt;
--ssh-audit n’est donc pas entièrement sans écriture.&lt;br /&gt;
--ssh-secure vérifie la syntaxe/effectivité et les connexions par clé avant/après&lt;br /&gt;
reload ; le mot de passe local reste utile à sudo.&lt;br /&gt;
--password-ajlsm utilise passwd interactif masqué ; aucun secret dans le YAML.&lt;br /&gt;
&lt;br /&gt;
La personnalisation système conserve dans la VM&lt;br /&gt;
/var/lib/ajlsm/system-personalisation/state.json et backup/. Ce journal décrit&lt;br /&gt;
une transaction, pas le cycle global. Ne pas l’effacer pour forcer une reprise.&lt;br /&gt;
La phase TLS vérifie le certificat interne /etc/ssl/ajlsm/server.crt, utilise&lt;br /&gt;
si nécessaire /usr/local/sbin/ajlsm-init-tls.sh déjà présent dans le modèle,&lt;br /&gt;
puis contrôle Apache. Cela ne valide pas les applications ou le TLS public.&lt;br /&gt;
Le README applicatif /home/ajlsm/README ne doit pas être remplacé par le&lt;br /&gt;
README-ajlsm-deploy de l’outil. Le document README-TEMPLATE3.txt est proposé&lt;br /&gt;
séparément, pas installé automatiquement.&lt;br /&gt;
&lt;br /&gt;
Validation YAML stricte : clés inconnues/répétées et types incorrects refusés ;&lt;br /&gt;
environnement/tags interne, client, prod, sans doublons ; tags [] admis ;&lt;br /&gt;
entiers positifs, mémoire minimale &amp;lt;= maximale, booléens true/false ;&lt;br /&gt;
interfaces netN/ensN uniques, IPv4/CIDR, loopback /32, DNS sans préfixe.&lt;br /&gt;
Passerelle dans le sous-réseau de son interface et distincte de la VM.&lt;br /&gt;
Serveur, bridge et stockage sont à adapter à l’infrastructure, sans liste&lt;br /&gt;
fermée inventée. Les sections métier sont désormais prises en charge :&lt;br /&gt;
l’interdiction historique d’ajouter metier ne s’applique plus à ce schéma.&lt;br /&gt;
&lt;br /&gt;
== Manuels, reprise et validation du lot ==&lt;br /&gt;
&lt;br /&gt;
Pages section 8 de la version 1.0.2 du 19 octobre : deploy, cycle, yaml, check, resources.&lt;br /&gt;
Lecture locale avec man ./man8/ajlsm-deploy.8 ; sauvegarde et installation&lt;br /&gt;
optionnelle décrites dans INSTALLATION-MANUELS.txt, sans copier les scripts.&lt;br /&gt;
Le lancement définitif se fait dans /opt/ajlsm-deploy/v1, sans copier les&lt;br /&gt;
programmes du nœud dans /usr/local/sbin. La commande invitée&lt;br /&gt;
/usr/local/sbin/ajlsm-init-tls.sh reste distincte et n&#039;est pas déplacée.&lt;br /&gt;
Conserver le lot complet, modules et modèles, sans mélanger les versions.&lt;br /&gt;
Une installation du lot ne remplace pas une recette complète sur Proxmox.&lt;br /&gt;
Tests locaux sous tests/, résultats dans RAPPORT-TESTS.txt ; QGA, SQL, PHP&lt;br /&gt;
et services simulés. Ils ne prouvent pas la réussite d&#039;un déploiement distant.&lt;br /&gt;
Une restauration de phase n&#039;annule pas SQL ni les actions web ultérieures.&lt;br /&gt;
Ne pas effacer un journal transaction.json pour forcer une reprise.&lt;br /&gt;
&lt;br /&gt;
== Réconciliation de la page reçue du 16 octobre et état de recette ==&lt;br /&gt;
&lt;br /&gt;
Cette procédure remplace les indications historiques « 11 étapes »,&lt;br /&gt;
« NFS/Apache/Matomo hors cycle » et « aucun journal global ». Le nouveau lot&lt;br /&gt;
compte 17 étapes avec publication protégée, mais la finalisation fonctionnelle&lt;br /&gt;
Matomo reste indépendante. L’ancien man reproduit intégralement dans la page&lt;br /&gt;
du 16 octobre n’est pas recopié ici : les cinq sources man8 de ce lot sont&lt;br /&gt;
la référence de version, sans procédure concurrente.&lt;br /&gt;
Les anciens chemins du 16 octobre restent des archives, pas le lot courant.&lt;br /&gt;
&lt;br /&gt;
Le cycle 16 étapes du lot consolide-taches a été exécuté sur un clone recréé&lt;br /&gt;
le 18 octobre, reprise TLS après faute de saisie incluse. Hostname et racine&lt;br /&gt;
ext4 97 Gio confirmés. Tâches Tomcat neutralisées pour les instances vides ;&lt;br /&gt;
les processus déjà lancés n’ont pas été arrêtés. Le correctif wait-online et&lt;br /&gt;
le nouveau cycle 17 étapes avec journal restent à valider sur Proxmox.&lt;br /&gt;
Les tests locaux ne sont pas une nouvelle recette distante.&lt;br /&gt;
La capture « Tables créées » et la première activation Matomo concernent le&lt;br /&gt;
clone antérieur : ne pas les attribuer automatiquement au clone actuel.&lt;br /&gt;
Le succès nominal ne valide pas le repli réseau après panne.&lt;br /&gt;
&lt;br /&gt;
Le modèle TEMPLATE3 n’a pas été modifié par ces scripts. Cela ne démontre&lt;br /&gt;
pas l’absence de toute autre intervention. Sa mise à jour OS demandée est&lt;br /&gt;
une maintenance à réaliser/valider séparément avant le prochain clonage.&lt;br /&gt;
Aucun nettoyage serveur ni envoi SVN n’est exécuté par cette livraison.&lt;br /&gt;
&lt;br /&gt;
[[Category:Proxmox]][[Category:AJLSM]][[Category:Déploiement]]&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=D%C3%A9ploiement_technique_d%E2%80%99une_VM_AJLSM&amp;diff=6500</id>
		<title>Déploiement technique d’une VM AJLSM</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=D%C3%A9ploiement_technique_d%E2%80%99une_VM_AJLSM&amp;diff=6500"/>
		<updated>2026-10-19T07:35:35Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= AJLSM-DEPLOY — Déploiement automatisé des VM Proxmox =&lt;br /&gt;
&lt;br /&gt;
Document consolidé au 16 octobre 2026. Cette procédure réunit la page du 15 octobre et la recette actuelle. Elle remplace leurs indications opérationnelles divergentes. L’original du 15 octobre reste archivé séparément.&lt;br /&gt;
&lt;br /&gt;
Référence technique : scripts reçus de Saturne3, puis lot de recette avec lanceur du cycle et assistant YAML.&lt;br /&gt;
&lt;br /&gt;
== 1. Périmètre et résultat de la recette ==&lt;br /&gt;
&lt;br /&gt;
Le cycle technique a été exécuté sur MERCURE3 sans erreur signalée. Les vérifications finales transmises confirment :&lt;br /&gt;
* connexion SSH avec le compte ajlsm ;&lt;br /&gt;
* élévation sudo avec le mot de passe défini pendant le cycle ;&lt;br /&gt;
* hostname mercure3.ajlsm.com ;&lt;br /&gt;
* volume racine ext4 de 97 Gio, dont 85 Gio disponibles lors du contrôle.&lt;br /&gt;
&lt;br /&gt;
Le cycle couvre le clonage, les ressources, l’initialisation du clone, l’extension de la racine, l’identité système, le réseau, SSH, le mot de passe et le certificat TLS interne.&lt;br /&gt;
&lt;br /&gt;
NFS, les configurations applicatives Apache2, Pleade, Drupal et Matomo ne font pas encore partie de ce cycle. Certains logiciels peuvent déjà être présents dans le modèle : leur présence ne constitue pas une configuration applicative du projet.&lt;br /&gt;
&lt;br /&gt;
== 2. Où exécuter les commandes ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Machine !! Rôle !! Exemple d’invite&lt;br /&gt;
|-&lt;br /&gt;
| Mac de l’administrateur || Transfert des archives par scp || Invite locale du Mac&lt;br /&gt;
|-&lt;br /&gt;
| Saturne3 || Préparation YAML, scripts Proxmox et cycle || root@Saturne3&lt;br /&gt;
|-&lt;br /&gt;
| MERCURE3 || Vérifications dans la VM || ajlsm@mercure3 ou root@mercure3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les scripts de déploiement sont exécutés sur Saturne3, pas dans MERCURE3.&lt;br /&gt;
Après « ssh ajlsm@10.0.0.43 », attendre l’invite de la VM avant de saisir les commandes suivantes.&lt;br /&gt;
Pour revenir de root@mercure3 à Saturne3 : un exit quitte sudo, puis un second exit ferme SSH.&lt;br /&gt;
&lt;br /&gt;
== 3. Organisation des fichiers ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/root/ajlsm-deploy/&lt;br /&gt;
  archives/                         Archives reçues, conservées comme références&lt;br /&gt;
  recettes/20261016/&lt;br /&gt;
    ajlsm-deploy-cycle/             Lot technique validé et assistant ajouté&lt;br /&gt;
    ajlsm-deploy-assistant/         Distribution de l’assistant et tests&lt;br /&gt;
    ajlsm-deploy-documentation/     Présent guide et modèles YAML&lt;br /&gt;
&lt;br /&gt;
/etc/ajlsm/deploy/projets/mercure3.yaml   Configuration actuellement utilisée&lt;br /&gt;
/usr/local/sbin/                        Scripts installés antérieurement&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le lot de recette contient ajlsm-deploy, ajlsm-deploy-check, ajlsm-deploy-resources, ajlsm-deploy-cycle et les modules ajlsm_deploy_common.py, ajlsm_deploy_rootgrow.py et ajlsm_deploy_postconfig.py. L’assistant ajlsm-deploy-yaml a été ajouté à ce même dossier.&lt;br /&gt;
&lt;br /&gt;
Conserver exécutables et modules ensemble. Utiliser les chemins ./ depuis le dossier de recette pour ne pas appeler une ancienne version de /usr/local/sbin.&lt;br /&gt;
Les anciennes archives « ajlsm-deploy-revise » et « correction-suggestions » ne sont pas la référence courante : elles précèdent les phases supplémentaires reçues dans l’archive serveur.&lt;br /&gt;
&lt;br /&gt;
Prérequis : Python 3.9 ou supérieur, PyYAML 6, outils Proxmox sur le nœud cible et prérequis du modèle AJLSM. Les phases invitées utilisent notamment l’agent QEMU, ajlsm-clone-init, Python, systemd et Netplan. L’extension actuelle cible ext4/LVM sur /dev/sda3, avec un seul PV et un seul LV.&lt;br /&gt;
&lt;br /&gt;
== 4. Les deux fichiers de préconfiguration ==&lt;br /&gt;
&lt;br /&gt;
=== 4.1. projet-vierge.yaml ===&lt;br /&gt;
&lt;br /&gt;
Ce modèle reprend toute la structure actuelle sans valeur opérationnelle préremplie. Chaque champ doit être renseigné. Seul proxmox.vmid peut rester null : il signifie alors attribution automatique.&lt;br /&gt;
&lt;br /&gt;
Le modèle comporte deux interfaces dont les valeurs sont null. Adapter le nombre d’interfaces avant la saisie si nécessaire. Pour déterminer ce nombre par les questions de l’assistant, utiliser plutôt le mode --new.&lt;br /&gt;
&lt;br /&gt;
Un modèle vierge est volontairement refusé par --check. Il ne doit jamais être passé directement au lanceur du cycle.&lt;br /&gt;
&lt;br /&gt;
=== 4.2. mercure3-reference.yaml ===&lt;br /&gt;
&lt;br /&gt;
Ce fichier conserve les valeurs du projet validé : modèle 506 sur Saturne3, nom MERCURE3, 8 vCPU, 24576 Mio de RAM maximale, 16384 Mio minimale, disque 100 Gio, extension racine activée et paramètres réseau du projet.&lt;br /&gt;
&lt;br /&gt;
Il permet de reconstruire une nouvelle VM avec la même configuration technique si le modèle, le stockage, les bridges et les préparatifs externes sont toujours disponibles. Il ne sauvegarde ni les données de l’ancienne VM, ni ses UUID, machine-id, clés hôte SSH ou mots de passe. Ces identités sont traitées par le cycle et ne sont pas à recopier.&lt;br /&gt;
&lt;br /&gt;
Avec vmid: null, le VMID de remplacement peut différer de celui de l’ancienne VM. Le VMID 505 observé pendant la recette n’est pas une réservation permanente.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ne pas lancer cette référence tant que MERCURE3 existe encore.&#039;&#039;&#039; Le clonage refuse un nom déjà présent. Pour tester une deuxième VM en parallèle, définir un autre nom, hostname, des IP distinctes et préparer DNS/OPNsense/Ansible en conséquence.&lt;br /&gt;
&lt;br /&gt;
=== 4.3. Valeurs acceptées ===&lt;br /&gt;
&lt;br /&gt;
* projet.environnement et tags : interne, client, prod. Les tags sont une liste sans doublons ; [] est admis.&lt;br /&gt;
* CPU, mémoire et taille du disque : entiers strictement positifs ; mémoire minimale inférieure ou égale à la maximale.&lt;br /&gt;
* Booléens : utiliser true ou false sans guillemets.&lt;br /&gt;
* Interfaces Proxmox : net suivi de chiffres ; interfaces invitées : ens suivi de chiffres.&lt;br /&gt;
* Adresses d’interfaces : IPv4/CIDR. Loopback : IPv4/32. Passerelle et DNS : IPv4 sans préfixe.&lt;br /&gt;
* Passerelle : interface déclarée et adresse appartenant à son sous-réseau, distincte des adresses de la VM.&lt;br /&gt;
* Hostname : nom DNS en minuscules.&lt;br /&gt;
* Serveur, bridge et stockage : valeurs adaptées à l’infrastructure ; aucune liste fermée inventée.&lt;br /&gt;
&lt;br /&gt;
Les clés inconnues ou répétées sont refusées. Ne pas ajouter de sections applicatives avant l’évolution coordonnée du schéma et des scripts. Ne pas utiliser [à renseigner] : les crochets créent une liste YAML.&lt;br /&gt;
&lt;br /&gt;
== 5. Préparer et valider le YAML ==&lt;br /&gt;
&lt;br /&gt;
Sur Saturne3, se placer dans le lot de recette :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5.1. Vérifier un fichier existant sans le modifier ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml /etc/ajlsm/deploy/projets/mercure3.yaml --check&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le message de succès signifie que les valeurs et leur cohérence locale sont conformes. Il ne certifie pas la préparation des services externes.&lt;br /&gt;
&lt;br /&gt;
Voici un exemple : &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;projet:&lt;br /&gt;
  code: mercure3&lt;br /&gt;
  nom: MERCURE3&lt;br /&gt;
  environnement: interne&lt;br /&gt;
&lt;br /&gt;
proxmox:&lt;br /&gt;
  serveur: Saturne3&lt;br /&gt;
  template_vmid: 506&lt;br /&gt;
  vmid: null&lt;br /&gt;
  nom_vm: MERCURE3&lt;br /&gt;
&lt;br /&gt;
  cpu:&lt;br /&gt;
    sockets: 1&lt;br /&gt;
    cores: 8&lt;br /&gt;
&lt;br /&gt;
  memoire:&lt;br /&gt;
    maximale_mib: 24576&lt;br /&gt;
    minimale_mib: 16384&lt;br /&gt;
&lt;br /&gt;
  disque_systeme:&lt;br /&gt;
    stockage: local-zfs&lt;br /&gt;
    taille_gib: 100&lt;br /&gt;
    etendre_volume_racine: true&lt;br /&gt;
&lt;br /&gt;
  demarrage_auto: true&lt;br /&gt;
&lt;br /&gt;
  tags:&lt;br /&gt;
    - interne&lt;br /&gt;
&lt;br /&gt;
systeme:&lt;br /&gt;
  hostname: mercure3.ajlsm.com&lt;br /&gt;
&lt;br /&gt;
reseau:&lt;br /&gt;
  interfaces:&lt;br /&gt;
    - nom: net0&lt;br /&gt;
      bridge: vmbr2&lt;br /&gt;
      systeme: ens18&lt;br /&gt;
      ipv4: 10.0.0.43/24&lt;br /&gt;
&lt;br /&gt;
    - nom: net1&lt;br /&gt;
      bridge: vmbr1&lt;br /&gt;
      systeme: ens19&lt;br /&gt;
      ipv4: 192.168.123.27/24&lt;br /&gt;
&lt;br /&gt;
  loopback:&lt;br /&gt;
    ipv4: 51.83.117.113/32&lt;br /&gt;
&lt;br /&gt;
  passerelle:&lt;br /&gt;
    ipv4: 10.0.0.4&lt;br /&gt;
    interface: ens18&lt;br /&gt;
&lt;br /&gt;
  dns:&lt;br /&gt;
    - 10.0.0.4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5.2. Compléter le modèle vierge ===&lt;br /&gt;
&lt;br /&gt;
Après extraction du présent lot documentaire :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml \&lt;br /&gt;
  /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-documentation/projet-vierge.yaml \&lt;br /&gt;
  --output /root/ajlsm-deploy/recettes/20261016/nouveau-projet.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Toutes les valeurs obligatoires seront demandées. Pour saisir de nouveau le projet MERCURE3, consulter mercure3-reference.yaml comme fiche de paramètres, sans lancer de déploiement.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;# Préconfiguration AJLSM vierge : aucune valeur d’infrastructure préremplie.&lt;br /&gt;
# Compléter avec ajlsm-deploy-yaml ; ne pas déployer ce modèle tel quel.&lt;br /&gt;
# null = champ à renseigner, SAUF proxmox.vmid où null = attribution automatique.&lt;br /&gt;
# Les crochets [à renseigner] sont interdits : ils représenteraient une liste YAML.&lt;br /&gt;
# Deux interfaces sont proposées : adapter leur nombre avant la saisie.&lt;br /&gt;
projet:&lt;br /&gt;
  code: null  # Obligatoire : minuscules/chiffres, tiret et souligné ; ex. mercure3.&lt;br /&gt;
  nom: null  # Obligatoire : nom lisible du projet.&lt;br /&gt;
  environnement: null  # Liste fermée : interne, client, prod.&lt;br /&gt;
&lt;br /&gt;
proxmox:&lt;br /&gt;
  serveur: null  # Obligatoire : nom du nœud Proxmox, ex. Saturne3.&lt;br /&gt;
  template_vmid: null  # Obligatoire : entier positif, VM modèle existante et arrêtée.&lt;br /&gt;
  vmid: null  # Automatique ; sinon entier positif différent de template_vmid.&lt;br /&gt;
  nom_vm: null  # Obligatoire : nom de VM, lettres/chiffres/point/tiret.&lt;br /&gt;
  cpu:&lt;br /&gt;
    sockets: null  # Obligatoire : entier positif.&lt;br /&gt;
    cores: null  # Obligatoire : entier positif ; vCPU = sockets × cores.&lt;br /&gt;
  memoire:&lt;br /&gt;
    maximale_mib: null  # Obligatoire : entier positif, en Mio.&lt;br /&gt;
    minimale_mib: null  # Obligatoire : entier positif, inférieur ou égal au maximum.&lt;br /&gt;
  disque_systeme:&lt;br /&gt;
    stockage: null  # Obligatoire : identifiant de stockage Proxmox existant.&lt;br /&gt;
    taille_gib: null  # Obligatoire : entier positif en Gio ; aucune réduction de disque.&lt;br /&gt;
    etendre_volume_racine: null  # Obligatoire : true ou false ; active la phase racine.&lt;br /&gt;
  demarrage_auto: null  # Obligatoire : true ou false ; appliqué à l’activation réseau.&lt;br /&gt;
  tags: null  # Obligatoire : liste ; interne/client/prod uniquement, sans doublons ; [] admis.&lt;br /&gt;
&lt;br /&gt;
systeme:&lt;br /&gt;
  hostname: null  # Obligatoire : nom DNS en minuscules ; vérifier sa déclaration en amont.&lt;br /&gt;
&lt;br /&gt;
reseau:&lt;br /&gt;
  interfaces:&lt;br /&gt;
    - nom: null  # Obligatoire : net suivi de chiffres, conforme à la VM modèle.&lt;br /&gt;
      bridge: null  # Obligatoire : bridge existant, au plus 15 caractères.&lt;br /&gt;
      systeme: null  # Obligatoire : ens suivi de chiffres, conforme au modèle actuel.&lt;br /&gt;
      ipv4: null  # Obligatoire : IPv4/CIDR, ex. 10.0.0.43/24 ; adresse unique.&lt;br /&gt;
    - nom: null&lt;br /&gt;
      bridge: null&lt;br /&gt;
      systeme: null&lt;br /&gt;
      ipv4: null&lt;br /&gt;
  loopback:&lt;br /&gt;
    ipv4: null  # Obligatoire : IPv4 avec préfixe /32, distincte des interfaces.&lt;br /&gt;
  passerelle:&lt;br /&gt;
    ipv4: null  # Obligatoire : IPv4 seule, dans le sous-réseau de son interface.&lt;br /&gt;
    interface: null  # Obligatoire : un des noms systeme déclarés ci-dessus.&lt;br /&gt;
  dns: null  # Obligatoire : liste non vide d’IPv4 sans préfixe, ex. [10.0.0.4].&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5.3. Créer sans modèle ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml /root/ajlsm-deploy/recettes/20261016/nouveau-projet.yaml --new&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette commande est une alternative à la précédente : le chemin doit être inexistant. L’assistant pose les questions, y compris le nombre d’interfaces, sans reprendre implicitement les valeurs de MERCURE3.&lt;br /&gt;
&lt;br /&gt;
=== 5.4. Revoir un projet renseigné ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml /etc/ajlsm/deploy/projets/mercure3.yaml --review \&lt;br /&gt;
  --output /root/ajlsm-deploy/recettes/20261016/mercure3-relecture.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Entrée conserve une valeur existante valide.&lt;br /&gt;
* ANNULER, Ctrl-C ou fin d’entrée abandonnent sans enregistrer.&lt;br /&gt;
* Tags et DNS sont saisis séparés par des virgules ; [] ou aucun signifie tags vides.&lt;br /&gt;
* Saisir auto ou null pour un VMID automatique.&lt;br /&gt;
* Après une incohérence, donner le chemin du champ à corriger ; ? affiche les chemins.&lt;br /&gt;
* Le résumé complet est présenté avant confirmation OUI/NON d’enregistrement.&lt;br /&gt;
&lt;br /&gt;
L’original reste intact, avec ses commentaires. La copie est réécrite en YAML, sans reprise des commentaires. Aucun fichier existant n’est écrasé. Si une destination existe, choisir un nouveau nom avec --output.&lt;br /&gt;
&lt;br /&gt;
=== 5.5. Préparatifs externes ===&lt;br /&gt;
&lt;br /&gt;
Avant une création, vérifier séparément la réservation des IP, les déclarations DNS, les règles/routes/NAT nécessaires dans OPNsense et l’inventaire ou les préparatifs Ansible. Ne pas inscrire de mots de passe dans le YAML ; conserver les secrets dans le dispositif prévu pour leur gestion.&lt;br /&gt;
&lt;br /&gt;
L’assistant actuel ne vérifie pas automatiquement ces services et ne marque pas un projet « prêt à déployer » sur cette seule base. Leur intégration reste à réaliser.&lt;br /&gt;
&lt;br /&gt;
Le contrôle Proxmox autonome examine notamment le modèle, ses ressources, le stockage et les bridges. Il concerne une nouvelle création et peut refuser un projet déjà déployé :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-check /chemin/vers/projet.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 6. Afficher le plan puis lancer le cycle ==&lt;br /&gt;
&lt;br /&gt;
=== 6.1. Plan sans exécution ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /chemin/vers/projet.yaml --plan&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le plan valide le YAML et affiche les commandes, sans exécuter les phases ni vérifier l’infrastructure. Il doit contenir les 11 étapes, toutes dans le dossier de recette.&lt;br /&gt;
&lt;br /&gt;
=== 6.2. Cycle réel pour une nouvelle VM ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /chemin/vers/projet.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le lanceur exécute les phases réelles, sans simulation automatique. Il attend seulement les confirmations, les saisies nécessaires et la fin de chaque commande. Il s’arrête sur refus ou erreur. Il ne répond pas à la place de l’administrateur et ne capture pas les mots de passe.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! N° !! Étape !! Commande réelle !! Simulation facultative&lt;br /&gt;
|-&lt;br /&gt;
| 1 || Clonage || --clone || --dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Ressources || --configure-resources || --resources-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Premier démarrage isolé || --first-boot-apply || --first-boot-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Extension partition/LVM/ext4 || --root-grow-apply || --root-grow-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Identité système || --system-apply || --system-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Préparation Netplan || --network-apply || --network-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Activation réseau || --network-enable || --network-enable-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Audit SSH || --ssh-audit || Aucune option dédiée&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Sécurisation SSH || --ssh-secure || Aucune option dédiée&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Mot de passe ajlsm || --password-ajlsm || Aucune option dédiée&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Certificat TLS interne || --tls-apply || Aucune option dédiée&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
L’extension racine est indispensable quand etendre_volume_racine vaut true. Agrandir le disque Proxmox ne suffit pas : la partition, le PV LVM, le LV et ext4 doivent aussi être étendus. Cette phase doit figurer après le premier démarrage, avant la personnalisation système. Avec false, la phase annonce sa désactivation.&lt;br /&gt;
&lt;br /&gt;
Le démarrage et la personnalisation se font réseau isolé. Netplan est préparé avant activation des liens. La phase d’activation contrôle le réseau et applique demarrage_auto.&lt;br /&gt;
&lt;br /&gt;
Le certificat TLS interne ne constitue pas, à lui seul, une configuration des applications du projet ou un certificat publiquement reconnu.&lt;br /&gt;
&lt;br /&gt;
=== 6.3. Mode manuel ===&lt;br /&gt;
&lt;br /&gt;
Chaque phase peut être lancée séparément avec ./ajlsm-deploy suivi du YAML et de son option. Après succès, le lot courant affiche deux lignes pour l’étape suivante : Simulation et Exécution. Si la simulation n’existe pas, il le signale. Aucune suggestion n’est exécutée automatiquement.&lt;br /&gt;
&lt;br /&gt;
Les simulations peuvent consulter l’invité et émettre des sondes ARP selon la phase : elles ne sont pas toutes des contrôles hors ligne. L’absence de réponse ARP ne remplace pas la réservation des adresses dans l’inventaire réseau.&lt;br /&gt;
&lt;br /&gt;
== 7. Erreur, annulation et reprise ==&lt;br /&gt;
&lt;br /&gt;
Conserver la sortie complète et diagnostiquer la phase fautive avant de reprendre. Une phase peut être partiellement effectuée ; le lanceur n’effectue ni suppression de VM ni restauration globale automatique.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /chemin/vers/projet.yaml --from extension-racine&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--from inclut l’étape indiquée et saute les précédentes à la demande de l’administrateur. Il ne certifie pas leur état. Les contrôles propres aux phases restent actifs. Le lanceur ne possède pas de journal persistant global de progression.&lt;br /&gt;
&lt;br /&gt;
Ne pas relancer le cycle depuis le clonage sur une VM existante pour terminer une étape. Ne pas relancer des étapes déjà terminées uniquement parce qu’une commande manuelle les suggère. Les suggestions suivent l’ordre théorique et ne constituent pas un inventaire de l’état de la VM.&lt;br /&gt;
&lt;br /&gt;
Codes de sortie : 0 succès, 1 annulation, 2 erreur. Le lanceur normalise les autres codes d’échec de ses sous-processus en erreur et ne poursuit pas.&lt;br /&gt;
&lt;br /&gt;
== 8. Vérifications finales ==&lt;br /&gt;
&lt;br /&gt;
Sur Saturne3, avec le VMID réellement annoncé au clonage :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
qm list&lt;br /&gt;
qm status VMID&lt;br /&gt;
qm config VMID&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remplacer VMID par l’identifiant vérifié. Contrôler le nom, les CPU, la RAM, le disque, les liens réseau et onboot selon le YAML.&lt;br /&gt;
&lt;br /&gt;
Depuis Saturne3, ouvrir la connexion et attendre l’invite de la VM :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh ajlsm@10.0.0.43&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dans MERCURE3, saisir sudo -i, attendre l’authentification et l’invite root, puis :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
hostname&lt;br /&gt;
lsblk&lt;br /&gt;
df -hT /&lt;br /&gt;
ip -br addr&lt;br /&gt;
ip route&lt;br /&gt;
resolvectl status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat vérifié pendant la recette : hostname mercure3.ajlsm.com, racine ext4 97 Gio. Les tailles disponibles évoluent avec l’utilisation. Les commandes SSH et TLS du cycle vérifient leurs propres résultats ; compléter par les tests d’accès attendus dans le réseau cible.&lt;br /&gt;
&lt;br /&gt;
== 9. Reconstruire MERCURE3 ultérieurement ==&lt;br /&gt;
&lt;br /&gt;
# Conserver le fichier mercure3-reference.yaml, le lot de scripts validé et l’identification du modèle utilisé.&lt;br /&gt;
# Comparer la référence au YAML effectivement utilisé avant reconstruction ; actualiser les changements d’infrastructure.&lt;br /&gt;
# Identifier et sauvegarder les données à conserver : le YAML n’est pas une sauvegarde de VM.&lt;br /&gt;
# Vérifier explicitement l’identité de l’ancienne VM et traiter séparément son arrêt et sa suppression volontaire. Le cycle ne détruit jamais automatiquement une VM existante.&lt;br /&gt;
# Contrôler DNS, OPNsense, Ansible et les réservations d’IP. Ne pas laisser deux VM actives avec les mêmes adresses.&lt;br /&gt;
# Valider la référence avec --check, afficher le --plan, puis lancer le cycle sur la référence après libération de la cible.&lt;br /&gt;
# Relever le nouveau VMID et effectuer les vérifications finales.&lt;br /&gt;
&lt;br /&gt;
On retrouve ainsi les paramètres de la VM, sans chercher à reproduire ses anciennes identités techniques.&lt;br /&gt;
&lt;br /&gt;
== 10. Protections et détails techniques ==&lt;br /&gt;
&lt;br /&gt;
=== 10.1. Isolation, identité et journal de personnalisation ===&lt;br /&gt;
&lt;br /&gt;
Le clone est arrêté après création, avec onboot désactivé et les interfaces isolées. Le premier démarrage s’effectue dans cet état d’isolation. Les phases système et réseau vérifient l’identité de la cible et l’UUID attendu selon leurs contrôles propres.&lt;br /&gt;
&lt;br /&gt;
La personnalisation système conserve dans l’invité :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/var/lib/ajlsm/system-personalisation/state.json&lt;br /&gt;
/var/lib/ajlsm/system-personalisation/backup/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce journal décrit la transaction d’identité, pas l’ensemble du cycle. Ne pas le supprimer pour forcer une nouvelle exécution. Après interruption, conserver les sauvegardes et examiner l’état réel avant reprise.&lt;br /&gt;
&lt;br /&gt;
La VM 515 est signalée comme hors périmètre par la documentation historique. Elle ne fait pas partie de la recette MERCURE3 et ne doit pas être ciblée par cette procédure.&lt;br /&gt;
&lt;br /&gt;
=== 10.2. Audit SSH : lecture dans la VM, écriture possible sur Saturne3 ===&lt;br /&gt;
&lt;br /&gt;
La phase --ssh-audit commence par synchroniser l’identité SSH :&lt;br /&gt;
# Lire la clé publique /etc/ssh/ssh_host_ed25519_key.pub dans la VM via l’agent QEMU.&lt;br /&gt;
# Valider le format ED25519 et sa structure binaire attendue.&lt;br /&gt;
# Lire indépendamment la clé exposée sur le réseau avec ssh-keyscan -T 8 -t ed25519.&lt;br /&gt;
# Comparer les clés : une divergence, une absence ou un format invalide provoque un refus.&lt;br /&gt;
# Après concordance seulement, sauvegarder /root/.ssh/known_hosts sur Saturne3, travailler sur une copie et remplacer le fichier avec la nouvelle entrée vérifiée pour l’IP cible.&lt;br /&gt;
# Contrôler les connexions par clé, les clés autorisées, sudo et l’état du compte ajlsm.&lt;br /&gt;
&lt;br /&gt;
Les autres entrées d’hôtes sont conservées ; le traitement retire aussi les anciennes entrées hachées correspondant à l’IP cible. Les sauvegardes utilisent le préfixe known_hosts.ajlsm-backup. dans /root/.ssh/.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;L’audit n’est donc pas entièrement sans écriture :&#039;&#039;&#039; ses lectures dans la VM sont accompagnées d’une mise à jour possible de known_hosts sur Saturne3. Ne jamais contourner une divergence en effaçant aveuglément known_hosts.&lt;br /&gt;
&lt;br /&gt;
=== 10.3. Sécurisation SSH et mot de passe ===&lt;br /&gt;
&lt;br /&gt;
--ssh-secure effectue un audit préalable, prépare un fichier SSH dédié, vérifie la syntaxe et les valeurs effectives, puis recharge SSH. Il désactive l’authentification SSH par mot de passe et conserve root par clé. Les connexions root et ajlsm par clé sont revérifiées par le code reçu.&lt;br /&gt;
&lt;br /&gt;
Le mot de passe local ajlsm reste utile pour sudo. --password-ajlsm utilise un terminal interactif et lance passwd dans la VM, avec sa double saisie masquée. Le secret n’est pas inscrit dans le YAML ni dans la ligne de commande. La procédure historique prévoit un report manuel dans le registre ODS d’administration ; appliquer les règles internes de gestion des secrets. Ne pas joindre ce registre à une documentation publique.&lt;br /&gt;
&lt;br /&gt;
=== 10.4. Certificat TLS interne et Apache ===&lt;br /&gt;
&lt;br /&gt;
--tls-apply lit le certificat /etc/ssl/ajlsm/server.crt. Si le CN et le SAN correspondent déjà au hostname attendu, la phase termine sans réinitialisation. Sinon, après confirmation, elle appelle /usr/local/sbin/ajlsm-init-tls.sh &#039;&#039;&#039;dans la VM&#039;&#039;&#039;. Ce dernier script doit être présent dans le modèle ; son contenu n’était pas inclus dans l’archive des scripts de déploiement reçue.&lt;br /&gt;
&lt;br /&gt;
Après une initialisation réussie, le module contrôle le certificat, apache2ctl configtest et systemctl is-active apache2. Ce contrôle technique d’Apache ne constitue pas une recette des VirtualHosts et des applications du projet.&lt;br /&gt;
&lt;br /&gt;
La documentation historique désigne /home/ajlsm/README, hérité de TEMPLATE3, comme README applicatif Pleade/Drupal. Le conserver séparément du README-ajlsm-deploy de l’outil de déploiement ; ne pas remplacer l’un par l’autre.&lt;br /&gt;
&lt;br /&gt;
=== 10.5. Attente réseau au premier démarrage ===&lt;br /&gt;
&lt;br /&gt;
La recette du 15 octobre signalait environ 60 secondes d’attente dans systemd-networkd-wait-online lorsque les interfaces étaient isolées. Ce constat historique n’a pas empêché l’agent QEMU ni ajlsm-clone-init de répondre. Une optimisation éventuelle du modèle reste distincte du déploiement ; ne pas désactiver le service sans vérifier ses dépendances.&lt;br /&gt;
&lt;br /&gt;
== 11. Maintenance, sauvegardes et manuel ==&lt;br /&gt;
&lt;br /&gt;
=== 11.1. Identifier les fichiers réellement exécutés ===&lt;br /&gt;
&lt;br /&gt;
La recette du 16 octobre utilise le dossier /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/. Elle ne démontre pas une mise à jour globale de /usr/local/sbin/. Toujours distinguer le lot validé et les programmes installés.&lt;br /&gt;
&lt;br /&gt;
Dans le dossier de recette :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy --help&lt;br /&gt;
./ajlsm-deploy-cycle --help&lt;br /&gt;
./ajlsm-deploy-yaml --help&lt;br /&gt;
python3 -m py_compile ajlsm-deploy ajlsm-deploy-check ajlsm-deploy-resources ajlsm-deploy-cycle ajlsm-deploy-yaml ajlsm_deploy_common.py ajlsm_deploy_rootgrow.py ajlsm_deploy_postconfig.py&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Une compilation vérifie la syntaxe, pas le bon déroulement d’une phase ni les prérequis serveur.&lt;br /&gt;
&lt;br /&gt;
=== 11.2. Sauvegarder et restaurer un lot cohérent ===&lt;br /&gt;
&lt;br /&gt;
Conserver ensemble programmes, modules et configuration de référence. Sauvegarder le lot complet avant une installation ou une correction. Exemple sur Saturne3 :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
tar -czf &amp;quot;/root/ajlsm-deploy/archives/lot-recette-$(date +%Y%m%d-%H%M%S).tar.gz&amp;quot; \&lt;br /&gt;
  -C /root/ajlsm-deploy/recettes/20261016 ajlsm-deploy-cycle&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Une restauration doit porter sur un ensemble compatible. Ne pas réinstaller uniquement ajlsm-deploy.bak-20261015 : ce fichier peut précéder les modules et phases nécessaires. L’ancienne sauvegarde et les répertoires de revue sont des références historiques à inventorier avant nettoyage.&lt;br /&gt;
&lt;br /&gt;
Ne pas supprimer INSTRUCTIONS-TEST.txt ou d’autres fichiers de /root/ajlsm-deploy-review/ sur la seule base de l’ancienne page. Leur archivage et le nettoyage ne font pas partie de cette mise à jour documentaire.&lt;br /&gt;
&lt;br /&gt;
=== 11.3. Page man ===&lt;br /&gt;
&lt;br /&gt;
La page du 15 octobre indique un manuel installé en /usr/local/man/man8/ajlsm-deploy.8 et une sauvegarde hors man8 dans /root/ajlsm-deploy-review/sauvegardes-man/. Ce sont des informations historiques, dont l’état actuel n’a pas été vérifié pendant la recette du 16 octobre.&lt;br /&gt;
&lt;br /&gt;
Pour identifier la page disponible sur Saturne3 :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man -w ajlsm-deploy&lt;br /&gt;
man 8 ajlsm-deploy&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Une page absente ne signifie pas que le script est absent : --help est l’aide intégrée de l’exécutable. Le manuel installé doit être réconcilié avec le cycle et l’assistant avant d’être considéré comme référence de cette version. En attendant, le présent guide et l’aide des fichiers du lot de recette décrivent le fonctionnement courant.&lt;br /&gt;
&lt;br /&gt;
Man le 16/10/2026&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
AJLSM-DEPLOY(8)                                     Administration système                                     AJLSM-DEPLOY(8)&lt;br /&gt;
&lt;br /&gt;
NOM&lt;br /&gt;
       ajlsm-deploy - déployer une VM Proxmox par phases contrôlées&lt;br /&gt;
&lt;br /&gt;
SYNOPSIS&lt;br /&gt;
       ajlsm-deploy projet.yaml PHASE [--agent-timeout secondes]&lt;br /&gt;
       ajlsm-deploy-check projet.yaml [--phase proxmox] [--yaml-only]&lt;br /&gt;
       ajlsm-deploy-resources projet.yaml (--dry-run | --apply)&lt;br /&gt;
&lt;br /&gt;
DESCRIPTION&lt;br /&gt;
       Programme  à  exécuter  sur  le  nœud Proxmox cible, avec les droits administrateur. Chaque invocation traite une seule&lt;br /&gt;
       phase.  Le YAML est validé avant les commandes externes.&lt;br /&gt;
&lt;br /&gt;
       Après succès, les suggestions affichent les commandes de simulation et d&#039;exécution de la prochaine étape, ou de l&#039;étape&lt;br /&gt;
       simulée.  Les étapes sans simulation dédiée le signalent explicitement.  Ces suggestions ne sont jamais  exécutées  au‐&lt;br /&gt;
       tomatiquement.  Elles décrivent l&#039;ordre théorique, sans mémoriser l&#039;état du cycle.&lt;br /&gt;
&lt;br /&gt;
       Pour  enchaîner les onze étapes sans en oublier, utiliser ajlsm-deploy-cycle(8).  Ce lanceur conserve les confirmations&lt;br /&gt;
       et les saisies interactives.&lt;br /&gt;
&lt;br /&gt;
ORDRE DES PHASES&lt;br /&gt;
       1. --clone&lt;br /&gt;
              Créer le clone complet, désactiver onboot, isoler les interfaces, vérifier l&#039;arrêt et les  adresses  MAC.  Aucun&lt;br /&gt;
              démarrage.  Simulation : --dry-run, qui comprend les précontrôles.&lt;br /&gt;
&lt;br /&gt;
       2. --configure-resources&lt;br /&gt;
              Configurer  et vérifier CPU, mémoire, balloon et disque scsi0.  Exige une VM arrêtée, onboot désactivé et inter‐&lt;br /&gt;
              faces isolées.  La réduction du disque est interdite.  Simulation : --resources-dry-run.&lt;br /&gt;
&lt;br /&gt;
       3. --first-boot-apply&lt;br /&gt;
              Démarrer le clone isolé, attendre l&#039;agent QEMU et ajlsm-clone-init, puis vérifier les identités  attendues.   Si&lt;br /&gt;
              la VM tourne déjà, reprendre les contrôles sans redémarrage.  Simulation : --first-boot-dry-run.&lt;br /&gt;
&lt;br /&gt;
       4. --root-grow-apply&lt;br /&gt;
              Après  le  premier démarrage et avant la personnalisation système, étendre la partition, le PV LVM, le LV racine&lt;br /&gt;
              et ext4.  Cette étape dépend de etendre_volume_racine dans le YAML.  Simulation : --root-grow-dry-run.&lt;br /&gt;
&lt;br /&gt;
       5. --system-apply&lt;br /&gt;
              Personnaliser hostname, hosts et machine-id, redémarrer isolé et vérifier l&#039;identité active. Respecter le  jour‐&lt;br /&gt;
              nal de transaction.  Simulation : --system-dry-run.&lt;br /&gt;
&lt;br /&gt;
       6. --network-apply&lt;br /&gt;
              Sauvegarder  et  écrire Netplan dans l&#039;invité, puis exécuter netplan generate. Les liens Proxmox restent isolés.&lt;br /&gt;
              Simulation : --network-dry-run.&lt;br /&gt;
&lt;br /&gt;
       7. --network-enable&lt;br /&gt;
              Contrôler identité, configuration et conflits ARP, activer les liens, vérifier adresses, loopback, route, DNS et&lt;br /&gt;
              passerelle, puis appliquer demarrage_auto.  Un mécanisme de repli tente de rétablir l&#039;isolation en cas  d&#039;échec.&lt;br /&gt;
              Simulation : --network-enable-dry-run.&lt;br /&gt;
&lt;br /&gt;
       8. --ssh-audit&lt;br /&gt;
              Comparer  la  clé  ED25519 lue via QEMU à celle exposée sur le réseau, actualiser known_hosts après concordance,&lt;br /&gt;
              puis vérifier les accès, clés autorisées, sudo et état du compte ajlsm.  Aucune simulation dédiée.&lt;br /&gt;
&lt;br /&gt;
       9. --ssh-secure&lt;br /&gt;
              Après audit et confirmation, désactiver l&#039;authentification SSH par mot de passe, conserver root par  clé,  véri‐&lt;br /&gt;
              fier  la  configuration,  recharger  SSH  et  contrôler les connexions root et ajlsm par clé.  Aucune simulation&lt;br /&gt;
              dédiée.&lt;br /&gt;
&lt;br /&gt;
       10. --password-ajlsm&lt;br /&gt;
              Ouvrir passwd pour ajlsm dans la VM avec double saisie native masquée.  Un terminal interactif est  obligatoire.&lt;br /&gt;
              Le mot de passe n&#039;est pas placé dans le YAML ni la ligne de commande.  Aucune simulation dédiée.&lt;br /&gt;
&lt;br /&gt;
       11. --tls-apply&lt;br /&gt;
              Vérifier  le  certificat TLS interne. Si CN et SAN correspondent déjà au hostname, ne pas réinitialiser.  Sinon,&lt;br /&gt;
              après confirmation, appeler ajlsm-init-tls.sh dans la VM, puis vérifier certificat, syntaxe  Apache  et  service&lt;br /&gt;
              actif.  Aucune simulation dédiée.&lt;br /&gt;
&lt;br /&gt;
OPTIONS COMMUNES&lt;br /&gt;
       --agent-timeout secondes&lt;br /&gt;
              Entier  strictement  positif,  défaut 300.  Délai transmis aux attentes utilisant l&#039;agent QEMU.  Il ne constitue&lt;br /&gt;
              pas un délai maximal global.  La phase d&#039;extension racine autorise au moins 600 secondes pour son exécution  in‐&lt;br /&gt;
              vitée après les précontrôles.&lt;br /&gt;
&lt;br /&gt;
       -h, --help&lt;br /&gt;
              Afficher l&#039;aide intégrée sans accéder à Proxmox.&lt;br /&gt;
&lt;br /&gt;
       Choisir  exactement une phase. Les noms des options du programme principal doivent être écrits en entier ; les abrévia‐&lt;br /&gt;
       tions telles que --network-dry sont refusées.&lt;br /&gt;
&lt;br /&gt;
CONFIRMATIONS&lt;br /&gt;
       Seul OUI, sans distinction de casse et après suppression des espaces périphériques, autorise une opération à  la  ques‐&lt;br /&gt;
       tion correspondante.  NON, vide, autre réponse, EOF ou interruption pendant la question annulent. Il n&#039;existe pas d&#039;op‐&lt;br /&gt;
       tion de confirmation automatique.  Une étape déjà conforme peut terminer sans modification ni nouvelle confirmation.&lt;br /&gt;
&lt;br /&gt;
EXTENSION RACINE&lt;br /&gt;
       Le  disque  Proxmox  agrandi  par  la phase ressources ne suffit pas à agrandir le système de fichiers de l&#039;invité.  La&lt;br /&gt;
       phase racine réalise growpart, pvresize et lvextend avec redimensionnement du système de fichiers.&lt;br /&gt;
&lt;br /&gt;
       Topologie prise en charge : racine ext4, PV /dev/sda3, partition terminale parmi trois partitions de /dev/sda, un  seul&lt;br /&gt;
       PV  et  un seul LV. La taille du disque doit correspondre au YAML. Les outils doivent déjà être présents ; aucun paquet&lt;br /&gt;
       n&#039;est installé par cette phase.&lt;br /&gt;
&lt;br /&gt;
       Si la partition est déjà agrandie, le code saute growpart et poursuit le traitement LVM. Si etendre_volume_racine  vaut&lt;br /&gt;
       false, la phase annonce sa désactivation. Vérifier ensuite lsblk et df -hT /.&lt;br /&gt;
&lt;br /&gt;
SSH ET TLS&lt;br /&gt;
       L&#039;audit  SSH  n&#039;est  pas  intégralement sans écriture : il peut sauvegarder et actualiser /root/.ssh/known_hosts sur le&lt;br /&gt;
       nœud Proxmox après comparaison indépendante des clés QEMU/réseau.  Une divergence provoque un refus ; ne pas  supprimer&lt;br /&gt;
       aveuglément known_hosts pour contourner ce contrôle.&lt;br /&gt;
&lt;br /&gt;
       La  structure  binaire ED25519 est contrôlée avant comparaison.  Une clé absente ou malformée provoque également un re‐&lt;br /&gt;
       fus.  Après concordance, les anciennes entrées de l&#039;IP cible, y compris hachées, sont retirées de la copie de  travail.&lt;br /&gt;
       Les autres hôtes sont conservés et le remplacement est atomique.&lt;br /&gt;
&lt;br /&gt;
       Le  mot de passe local ajlsm reste utile pour sudo même lorsque l&#039;authentification SSH par mot de passe est désactivée.&lt;br /&gt;
       Le conserver selon la procédure interne de gestion des secrets.  La procédure AJLSM prévoit un report  manuel  dans  le&lt;br /&gt;
       registre ODS d&#039;administration ; ne pas inclure ce registre dans le YAML.&lt;br /&gt;
&lt;br /&gt;
       Le  certificat  interne  et le contrôle technique d&#039;Apache ne valident pas les VirtualHosts ni les applications. ajlsm-&lt;br /&gt;
       init-tls.sh doit être présent dans l&#039;invité ; son contenu n&#039;est pas fourni par le lot de scripts du nœud Proxmox.&lt;br /&gt;
&lt;br /&gt;
FORMAT YAML&lt;br /&gt;
       Sections obligatoires : projet, proxmox, systeme et reseau.  Les clés inconnues, répétées ou manquantes sont  refusées.&lt;br /&gt;
       Seul  proxmox.vmid  peut rester null pour une attribution automatique.  Ce VMID n&#039;est pas réservé avant clonage et peut&lt;br /&gt;
       changer.&lt;br /&gt;
&lt;br /&gt;
       projet.environnement et tags acceptent interne, client ou prod.  Les tags forment une liste sans doublon ; []  est  ad‐&lt;br /&gt;
       mis.   Les  ressources  exigent des entiers positifs ; la mémoire minimale ne dépasse pas la maximale. Utiliser true ou&lt;br /&gt;
       false pour les booléens.&lt;br /&gt;
&lt;br /&gt;
       Les chaînes numériques et les booléens ne sont pas convertis en entiers par le validateur. Le VMID explicite doit  être&lt;br /&gt;
       différent du template_vmid. Aucune correspondance automatique n&#039;est imposée entre l&#039;environnement et les tags.&lt;br /&gt;
&lt;br /&gt;
       Hostname DNS en minuscules ; interfaces Proxmox netN et invitées ensN.  Les IPv4 d&#039;interfaces exigent un préfixe CIDR ;&lt;br /&gt;
       la  loopback  exige  /32.  La passerelle est dans le sous-réseau de son interface déclarée.  Les interfaces et adresses&lt;br /&gt;
       sont uniques.  Les DNS forment une liste non vide d&#039;IPv4 sans préfixe.  La passerelle doit différer  des  adresses  des&lt;br /&gt;
       interfaces.   Les adresses réseau et broadcast sont refusées pour les sous-réseaux de préfixe inférieur à 31.  Serveur,&lt;br /&gt;
       stockage et bridge restent des valeurs d&#039;infrastructure à renseigner ; aucune liste  fermée  n&#039;est  inventée  pour  ces&lt;br /&gt;
       champs.&lt;br /&gt;
&lt;br /&gt;
       Préparer  le  fichier  avec  ajlsm-deploy-yaml(8).   projet-vierge.yaml  est volontairement incomplet.  mercure3-refer‐&lt;br /&gt;
       ence.yaml conserve les paramètres de reconstruction, pas les données, secrets ou anciennes identités de la VM.&lt;br /&gt;
&lt;br /&gt;
AUXILIAIRES&lt;br /&gt;
       ajlsm-deploy-check&lt;br /&gt;
              Valider le YAML, puis contrôler le modèle, ses  ressources,  le  stockage  et  les  bridges  pour  une  nouvelle&lt;br /&gt;
              création.   --phase  accepte uniquement proxmox.  --yaml-only effectue seulement la validation locale, sans com‐&lt;br /&gt;
              mande Proxmox. Une VM de projet déjà existante peut faire échouer les contrôles de nouvelle création.&lt;br /&gt;
&lt;br /&gt;
       ajlsm-deploy-resources&lt;br /&gt;
              Configurer les ressources avec --apply, ou simuler avec --dry-run. Ces modes  sont  exclusifs  et  obligatoires.&lt;br /&gt;
              Les  protections sont revérifiées avant chaque écriture.  Le programme refuse notamment une cible modèle ou con‐&lt;br /&gt;
              fondue avec la source, et un VMID explicite incohérent.&lt;br /&gt;
&lt;br /&gt;
PRÉREQUIS&lt;br /&gt;
       Python 3.9 ou supérieur, PyYAML 6, outils Proxmox et outils réseau.  Conserver le principal, ses  deux  auxiliaires  et&lt;br /&gt;
       les  modules  common, rootgrow et postconfig dans le même répertoire.  Les auxiliaires doivent être exécutables et leur&lt;br /&gt;
       Python doit disposer de PyYAML.&lt;br /&gt;
&lt;br /&gt;
       Le modèle arrêté doit disposer de l&#039;agent QEMU, ajlsm-clone-init, Python, systemd, Netplan, outils LVM et outils  d&#039;ex‐&lt;br /&gt;
       tension.  Les phases postréseau nécessitent les accès SSH par clé prévus et le script TLS invité.&lt;br /&gt;
&lt;br /&gt;
FICHIERS&lt;br /&gt;
       /etc/ajlsm/deploy/projets/&lt;br /&gt;
              Configurations des projets.&lt;br /&gt;
&lt;br /&gt;
       /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/&lt;br /&gt;
              Lot de recette validé le 16 octobre 2026.  Utiliser les chemins ./ pour ne pas appeler une ancienne version.&lt;br /&gt;
&lt;br /&gt;
       /usr/local/sbin/&lt;br /&gt;
              Programmes installés antérieurement ; leur mise à jour n&#039;est pas prouvée par le succès du lot de recette.&lt;br /&gt;
&lt;br /&gt;
       /var/lib/ajlsm/system-personalisation/&lt;br /&gt;
              Journal et sauvegardes d&#039;identité dans l&#039;invité.  Ne pas effacer pour forcer une reprise.&lt;br /&gt;
&lt;br /&gt;
LIMITES&lt;br /&gt;
       Les  simulations  ne  sont pas toutes hors ligne : la simulation d&#039;activation réseau émet des sondes ARP.  L&#039;absence de&lt;br /&gt;
       réponse ne garantit pas la disponibilité d&#039;une IP.  Le repli réseau en situation réelle reste à recetter.&lt;br /&gt;
&lt;br /&gt;
       Les validations locales ne certifient pas DNS, OPNsense ou Ansible.   NFS,  VirtualHosts  Apache2,  Pleade,  Drupal  et&lt;br /&gt;
       Matomo restent hors du cycle applicatif actuellement implémenté.&lt;br /&gt;
&lt;br /&gt;
       Le  README  applicatif /home/ajlsm/README hérité du modèle est distinct du README de déploiement. Ne pas remplacer l&#039;un&lt;br /&gt;
       par l&#039;autre.&lt;br /&gt;
&lt;br /&gt;
CODES DE SORTIE&lt;br /&gt;
       0 : succès. 1 : annulation. 2 : erreur.  L&#039;aide quitte avec 0 ; une erreur d&#039;arguments quitte avec 2.&lt;br /&gt;
&lt;br /&gt;
EXEMPLES&lt;br /&gt;
       Depuis le dossier de recette, sur Saturne3 :&lt;br /&gt;
       ./ajlsm-deploy-check projet.yaml --yaml-only&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --dry-run&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --clone&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --resources-dry-run&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --configure-resources&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --first-boot-dry-run&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --first-boot-apply&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --root-grow-dry-run&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --root-grow-apply&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --system-dry-run&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --system-apply&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --network-dry-run&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --network-apply&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --network-enable-dry-run&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --network-enable&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --ssh-audit&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --ssh-secure&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --password-ajlsm&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --tls-apply&lt;br /&gt;
       Les simulations sont facultatives. Le mode manuel exige le contrôle de l&#039;ordre des phases. Pour l&#039;enchaînement guidé :&lt;br /&gt;
       ./ajlsm-deploy-cycle projet.yaml --plan&lt;br /&gt;
       ./ajlsm-deploy-cycle projet.yaml&lt;br /&gt;
       Ne pas relancer un cycle de création sur MERCURE3 déjà déployée.&lt;br /&gt;
&lt;br /&gt;
ÉTAT DE LA RECETTE&lt;br /&gt;
       Le manuel installé reçu portait la date du 15 octobre 2026.  Il décrivait déjà les phases racine, SSH et TLS, mais  pas&lt;br /&gt;
       le nouveau lanceur ni l&#039;assistant YAML.&lt;br /&gt;
&lt;br /&gt;
       Le  16 octobre, les sorties transmises ont confirmé la fin du cycle complet sur MERCURE3. Les vérifications finales ont&lt;br /&gt;
       confirmé SSH, sudo, mercure3.ajlsm.com et une racine ext4 de 97 Gio.  Les scénarios négatifs de clés SSH  étaient  rap‐&lt;br /&gt;
       portés  comme  tests  isolés  du  15 octobre ; ils n&#039;ont pas été rejoués lors de la présente révision documentaire.  Le&lt;br /&gt;
       repli réseau réel reste distinct de cette recette nominale.&lt;br /&gt;
&lt;br /&gt;
VOIR AUSSI&lt;br /&gt;
       ajlsm-deploy-cycle(8), ajlsm-deploy-yaml(8), qm(1), lvm(8).&lt;br /&gt;
&lt;br /&gt;
AJLSM                                                  October 16, 2026                                        AJLSM-DEPLOY(8)&lt;br /&gt;
~&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 12. État des validations et limites ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Date / source !! Vérification !! Portée&lt;br /&gt;
|-&lt;br /&gt;
| 15/10/2026, page historique || Déploiements initiaux jusqu’à l’activation réseau || Résultats historiques conservés ; ne décrivent pas à eux seuls le cycle actuel&lt;br /&gt;
|-&lt;br /&gt;
| 15/10/2026, page historique || Comparaison ED25519, clés divergentes ou malformées, préservation de known_hosts || Tests isolés rapportés dans la documentation reçue, non rejoués lors de cette consolidation&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, tests locaux du lot cycle || Ordre des 11 étapes, arrêt sur refus/erreur, reprise et suggestions || 8 tests réussis, incluant des sous-cas ; sous-processus des phases simulés&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, sorties Saturne3 transmises || Cycle technique complet sur un nouveau clone MERCURE3 || Terminé sans erreur signalée, extension racine incluse&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, sorties invitées transmises || SSH ajlsm, sudo, hostname et racine ext4 || Confirmés ; mercure3.ajlsm.com et 97 Gio pour /&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, tests locaux assistant || Création, correction, copie, validation et annulation || 14 tests réussis, saisies simulées&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, sortie Saturne3 transmise || Assistant --check sur mercure3.yaml || Valeurs YAML valides ; aucune écriture ni validation externe&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, vérification locale des modèles || Modèle vierge complété par l’assistant || Paramètres identiques à la référence MERCURE3 ; original intact&lt;br /&gt;
|-&lt;br /&gt;
| À réaliser || Essai réel du mécanisme de repli après échec d’activation réseau || Non confirmé ; le succès du parcours nominal ne valide pas ce scénario&lt;br /&gt;
|-&lt;br /&gt;
| À réaliser || Vérifications automatiques DNS, OPNsense, Ansible et recette applicative || Hors périmètre actuel&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le message de fin du cycle signifie que ses phases ont retourné un succès. Il ne vaut pas validation des applications ni détection de toutes les défaillances possibles. Conserver les vérifications finales et les limites propres aux phases.&lt;br /&gt;
&lt;br /&gt;
== 13. Réconciliation avec la page du 15 octobre ==&lt;br /&gt;
&lt;br /&gt;
L’original reçu est conservé intégralement dans historique/guide-20261015.mediawiki. Il sert de trace, pas de seconde procédure opérationnelle concurrente.&lt;br /&gt;
&lt;br /&gt;
Le présent document remplace les indications opérationnelles anciennes :&lt;br /&gt;
* confirmations CLONER/APPLIQUER/DEMARRER remplacées par OUI/NON ;&lt;br /&gt;
* parcours manuel seul remplacé par le choix entre mode manuel et cycle interactif ;&lt;br /&gt;
* liste des étapes incluant l’extension racine, SSH, mot de passe et TLS ;&lt;br /&gt;
* extension racine et cycle complet désormais validés sur la recette du 16 octobre ;&lt;br /&gt;
* suggestions manuelles affichant les deux commandes disponibles, sans oublier l’extension racine ;&lt;br /&gt;
* création et relecture du YAML par l’assistant, sans écraser l’original ;&lt;br /&gt;
* ajout du modèle vierge et de la référence MERCURE3 renseignée ;&lt;br /&gt;
* séparation explicite des scripts installés, du lot de recette, du manuel historique et de la future installation.&lt;br /&gt;
&lt;br /&gt;
Les détails encore utiles de l’ancienne page sur l’isolation, les transactions, ED25519, les sauvegardes, le README applicatif et les limites de validation sont repris ci-dessus. Une nouvelle mise à jour fonctionnelle doit modifier cette procédure directement plutôt que superposer une nouvelle section corrective à une ancienne procédure contradictoire.&lt;br /&gt;
&lt;br /&gt;
== 14. Suites prévues ==&lt;br /&gt;
&lt;br /&gt;
Prévoir les paramètres NFS, sites Apache2, Pleade, Drupal et Matomo dans le même YAML lorsque leurs exigences seront définies. Modifier ensemble le schéma, l’assistant, les modèles, les précontrôles, les phases et leur documentation. Documenter les références aux secrets plutôt que leurs valeurs.&lt;br /&gt;
&lt;br /&gt;
L’intégration des contrôles DNS, OPNsense et Ansible précédera une déclaration automatisée de disponibilité du projet. Le modèle actuel ne contient pas encore ces nouvelles sections.&lt;br /&gt;
&lt;br /&gt;
[[Catégorie:Infrastructure]]&lt;br /&gt;
[[Catégorie:Proxmox]]&lt;br /&gt;
[[Catégorie:Déploiement]]&lt;br /&gt;
[[Catégorie:AJLSM]]&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=D%C3%A9ploiement_technique_d%E2%80%99une_VM_AJLSM&amp;diff=6499</id>
		<title>Déploiement technique d’une VM AJLSM</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=D%C3%A9ploiement_technique_d%E2%80%99une_VM_AJLSM&amp;diff=6499"/>
		<updated>2026-10-19T07:35:05Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= AJLSM-DEPLOY — Version 1.0.2 =&lt;br /&gt;
&lt;br /&gt;
Mise à jour : 19 octobre 2026. Ce guide décrit les scripts du dossier&lt;br /&gt;
&#039;&#039;&#039;ajlsm-deploy-v1.0.2&#039;&#039;&#039;, à installer dans &#039;&#039;&#039;/opt/ajlsm-deploy/v1&#039;&#039;&#039;.&lt;br /&gt;
Ce chemin est le répertoire définitif de lancement sur le nœud Proxmox ;&lt;br /&gt;
les anciennes copies de /usr/local/sbin ne sont pas remplacées implicitement.&lt;br /&gt;
Les lots NFS, Apache et Matomo précédents sont historiques. Garder scripts,&lt;br /&gt;
modules et modèles du même lot. Rotation des logs et update.sh hors périmètre.&lt;br /&gt;
&lt;br /&gt;
== Périmètre et architecture ==&lt;br /&gt;
&lt;br /&gt;
Les scripts tournent sur le nœud Proxmox. Ils configurent le clone depuis un&lt;br /&gt;
projet YAML strict, utilisent QEMU Guest Agent pour les opérations invitées,&lt;br /&gt;
et SSH pour certaines vérifications/postconfigurations. Le moteur principal&lt;br /&gt;
orchestre les phases ; les modules spécialisés traitent racine, postconfiguration,&lt;br /&gt;
NFS, Apache, SQL Matomo, activation Matomo et inventaire des tâches planifiées.&lt;br /&gt;
Les helpers communs valident le YAML et affichent les commandes suivantes.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ce n&#039;est pas un gestionnaire complet de l&#039;infrastructure externe.&#039;&#039;&#039; DNS,&lt;br /&gt;
OPNsense, Ansible, autorisation Eole3 et certificats publics ont leurs procédures.&lt;br /&gt;
Le script ne détruit pas la VM existante et ne modifie pas TEMPLATE3.&lt;br /&gt;
&lt;br /&gt;
== Répertoire définitif et exemple MERCURE3 ==&lt;br /&gt;
&lt;br /&gt;
Les cinq programmes affichent la version 1.0.2 avec --version.&lt;br /&gt;
Leur --help rappelle le même répertoire et le même exemple que cette page.&lt;br /&gt;
Ces valeurs sont centralisées dans ajlsm_deploy_version.py.&lt;br /&gt;
Les suggestions visent les programmes du dossier réellement exécuté :&lt;br /&gt;
utiliser le lot installé ci-dessous, pas un ancien dossier de recette.&lt;br /&gt;
&lt;br /&gt;
Sur Saturne3, après installation du lot complet selon INSTALLATION-V1.txt :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /opt/ajlsm-deploy/v1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Toutes les commandes ./ de cette page se lancent depuis ce répertoire.&lt;br /&gt;
Depuis un autre répertoire du même nœud, utiliser le chemin absolu du&lt;br /&gt;
programme sous /opt/ajlsm-deploy/v1 et celui du YAML.&lt;br /&gt;
Les YAML opérationnels restent sous /etc/ajlsm/deploy/projets/,&lt;br /&gt;
les journaux sous /var/lib/ajlsm-deploy/cycles/. Les archives/recettes&lt;br /&gt;
sous /root/ajlsm-deploy ne sont plus le répertoire de lancement v1.&lt;br /&gt;
Ne pas mélanger les modules ou changer de lot pendant un cycle.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;exemples/mercure3-exemple.yaml&#039;&#039;&#039; est un exemple renseigné avec les IP&lt;br /&gt;
réelles de MERCURE3, pas une préconfiguration générique.&lt;br /&gt;
Les commandes MERCURE3 de ce guide sont des exemples à adapter au projet.&lt;br /&gt;
Le nom de la VM, ses DNS et ses fichiers YAML opérationnels existants ne sont&lt;br /&gt;
pas renommés. En particulier, conserver le chemin du YAML pour la reprise :&lt;br /&gt;
le journal est indexé par ce chemin absolu.&lt;br /&gt;
modeles/projet-vierge.yaml demeure le modèle générique sans valeurs.&lt;br /&gt;
&lt;br /&gt;
== Prérequis impératif : OS de TEMPLATE3 à jour ==&lt;br /&gt;
&lt;br /&gt;
Avant TOUT nouveau clonage, maintenir l’OS Ubuntu de TEMPLATE3 à jour.&lt;br /&gt;
La VM clonée hérite de cet état. Maintenance manuelle distincte : les scripts&lt;br /&gt;
de déploiement ne mettent pas le modèle à jour. Prévoir une sauvegarde&lt;br /&gt;
récupérable et une fenêtre sans conflit d’IP avec les clones existants.&lt;br /&gt;
Ne pas démarrer ni convertir à l’aveugle un modèle marqué template Proxmox.&lt;br /&gt;
&lt;br /&gt;
Dans la console de TEMPLATE3, après vérification de son identité :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
hostname -f&lt;br /&gt;
cat /etc/os-release&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt upgrade&lt;br /&gt;
apt list --upgradable&lt;br /&gt;
if [ -f /var/run/reboot-required ]; then&lt;br /&gt;
  cat /var/run/reboot-required&lt;br /&gt;
  cat /var/run/reboot-required.pkgs 2&amp;gt;/dev/null || true&lt;br /&gt;
fi&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Examiner toutes les erreurs, messages APT et paquets retenus/différés.&lt;br /&gt;
apt update seul ne met pas les paquets à jour. Pas de -y, full-upgrade,&lt;br /&gt;
do-release-upgrade ou update.sh automatique. Si un redémarrage est demandé :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo reboot&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Attendre le retour du modèle, puis dans sa console :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
hostname -f&lt;br /&gt;
uname -r&lt;br /&gt;
systemctl --failed&lt;br /&gt;
apt list --upgradable&lt;br /&gt;
test ! -f /var/run/reboot-required&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Examiner les résultats, noter date/OS/noyau dans le registre de maintenance.&lt;br /&gt;
Après validation, arrêter proprement TEMPLATE3 :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo shutdown -h now&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puis sur Saturne3 :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
qm status 506&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
506 correspond au template_vmid de cette recette : vérifier la valeur du YAML.&lt;br /&gt;
Le modèle doit être arrêté avant le clonage. Ni le lanceur ni les précontrôles&lt;br /&gt;
ne certifient automatiquement sa fraîcheur APT. Cette maintenance n’a pas&lt;br /&gt;
été réalisée par les scripts livrés. Saturne3 et HAProxy ont leur maintenance&lt;br /&gt;
distincte, non demandée ici.&lt;br /&gt;
Voir PREREQUIS-OS-ET-PUBLICATION.txt et les documentations Ubuntu :&lt;br /&gt;
[https://ubuntu.com/server/docs/how-to/software/package-management/ Gestion des paquets]&lt;br /&gt;
et [https://ubuntu.com/server/docs/how-to/software/automatic-updates/ Mises à jour automatiques].&lt;br /&gt;
&lt;br /&gt;
== Paramètres prévus avant la création ==&lt;br /&gt;
&lt;br /&gt;
* Identité projet, environnement et tags : interne, client, prod ; types YAML stricts.&lt;br /&gt;
* Ressources, template, stockage, IP privées/VPN/publique, passerelle et DNS.&lt;br /&gt;
* Domaines principal, préprod et Matomo définitifs, sans https:// ni chemin.&lt;br /&gt;
* NFS existant et droits accordés par l&#039;administrateur du serveur.&lt;br /&gt;
* Activation des vhosts distincte de l&#039;installation des logiciels.&lt;br /&gt;
* Noms SQL dédiés Matomo, sans secret dans le YAML.&lt;br /&gt;
&lt;br /&gt;
Référence MERCURE3 : hostname mercure3.ajlsm.com, VPN 10.0.0.43,&lt;br /&gt;
réseau données 192.168.123.27, publique 51.83.117.113. Matomo :&lt;br /&gt;
mercure3-matomo.pleade.com ; préprod : mercure3-preprod.pleade.com.&lt;br /&gt;
Ne pas conserver deux VM avec ces mêmes adresses.&lt;br /&gt;
&lt;br /&gt;
Chez OVH, principal A vers 51.83.117.113, domaines secondaires CNAME vers&lt;br /&gt;
mercure3.ajlsm.com dans la recette. Ne pas publier d&#039;AAAA sans IPv6 opérationnel.&lt;br /&gt;
Pour un domaine secondaire sur la même IP, réutiliser la VIP/NAT existante si&lt;br /&gt;
elle et le filtrage traitent déjà le flux requis ; ne pas dupliquer OPNsense.&lt;br /&gt;
Le trafic public passe par la VIP HAProxy 10.0.0.32, nœuds .30 et .31.&lt;br /&gt;
&lt;br /&gt;
== Préconfiguration et contrôle ==&lt;br /&gt;
&lt;br /&gt;
modeles/projet-vierge.yaml contient des null, jamais une liste [à renseigner].&lt;br /&gt;
null est valide pour proxmox.vmid automatique, pas pour un champ obligatoire.&lt;br /&gt;
Les sections métier peuvent être omises, mais doivent être complètes si présentes.&lt;br /&gt;
exemples/mercure3-exemple.yaml prépare une recréation volontaire, pas une VM parallèle.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml ./modeles/projet-vierge.yaml --with-metier --output /etc/ajlsm/deploy/projets/mercure3-initial.yaml&lt;br /&gt;
./ajlsm-deploy-yaml /etc/ajlsm/deploy/projets/mercure3-initial.yaml --check&lt;br /&gt;
./ajlsm-deploy-cycle /etc/ajlsm/deploy/projets/mercure3-initial.yaml --plan&lt;br /&gt;
./ajlsm-deploy-check /etc/ajlsm/deploy/projets/mercure3-initial.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le parcours complet de l&#039;assistant est désormais &#039;&#039;&#039;--with-metier&#039;&#039;&#039; :&lt;br /&gt;
NFS, domaines Matomo/Apache et SQL dédiés dans le même YAML initial.&lt;br /&gt;
Sans modèle, utiliser --new --with-metier avec un chemin inexistant.&lt;br /&gt;
Les valeurs valides existantes sont conservées ; --review les revoit aussi.&lt;br /&gt;
Le guide détaillé GUIDE-YAML.txt décrit les questions et les activations :&lt;br /&gt;
Drupal seulement si vérifié, Pleade préprod désactivé en son absence,&lt;br /&gt;
Matomo Apache false jusqu&#039;à publication-matomo après pause externe.&lt;br /&gt;
Le mode --with-matomo-site reste une activation MANUELLE distincte,&lt;br /&gt;
incompatible avec --with-metier ; inutile au cycle guidé actuel.&lt;br /&gt;
OS du modèle, DNS, OPNsense, ACME sur les deux HAProxy, Ansible/whitelist&lt;br /&gt;
et autorisation NFS sont rappelés mais pas vérifiés ni enregistrés comme tels.&lt;br /&gt;
&lt;br /&gt;
Les options individuelles restent disponibles : --with-nfs, --with-matomo, --with-apache et&lt;br /&gt;
--with-matomo-sql ; --review revoit aussi les valeurs valides. --new crée un&lt;br /&gt;
nouveau chemin. Les fichiers existants ne sont pas écrasés. --check et&lt;br /&gt;
--yaml-only sont des contrôles locaux, pas une vérification d&#039;infrastructure.&lt;br /&gt;
Prévoir apache.matomo.activer=false pour le cycle initial ; un projet&lt;br /&gt;
d&#039;activation true est refusé par le cycle avant toute phase passant par Apache.&lt;br /&gt;
&lt;br /&gt;
== Cycle initial : dix-sept étapes ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Étape !! Simulation / lecture !! Exécution&lt;br /&gt;
|-&lt;br /&gt;
| clonage || --dry-run || --clone&lt;br /&gt;
|-&lt;br /&gt;
| ressources || --resources-dry-run || --configure-resources&lt;br /&gt;
|-&lt;br /&gt;
| premier-demarrage || --first-boot-dry-run || --first-boot-apply&lt;br /&gt;
|-&lt;br /&gt;
| extension-racine || --root-grow-dry-run || --root-grow-apply&lt;br /&gt;
|-&lt;br /&gt;
| identite || --system-dry-run || --system-apply&lt;br /&gt;
|-&lt;br /&gt;
| netplan || --network-dry-run || --network-apply&lt;br /&gt;
|-&lt;br /&gt;
| activation-reseau || --network-enable-dry-run || --network-enable&lt;br /&gt;
|-&lt;br /&gt;
| audit-ssh || --ssh-audit || audit, pas de simulation distincte&lt;br /&gt;
|-&lt;br /&gt;
| securisation-ssh || aucune || --ssh-secure&lt;br /&gt;
|-&lt;br /&gt;
| mot-de-passe || aucune || --password-ajlsm&lt;br /&gt;
|-&lt;br /&gt;
| tls || aucune || --tls-apply&lt;br /&gt;
|-&lt;br /&gt;
| nfs || --nfs-dry-run puis --nfs-check || --nfs-apply&lt;br /&gt;
|-&lt;br /&gt;
| apache || --apache-dry-run || --apache-apply&lt;br /&gt;
|-&lt;br /&gt;
| matomo-sql || --matomo-sql-dry-run || --matomo-sql-prepare&lt;br /&gt;
|-&lt;br /&gt;
| tomcat-cron || --scheduled-dry-run || --scheduled-apply&lt;br /&gt;
|-&lt;br /&gt;
| taches-planifiees || --scheduled-audit || aucune modification&lt;br /&gt;
|-&lt;br /&gt;
| publication-matomo || --matomo-guided-dry-run || --matomo-guided&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le clone est isolé avant premier démarrage. L&#039;extension racine suit le premier&lt;br /&gt;
démarrage et ne doit pas être confondue avec le disque virtuel déjà agrandi.&lt;br /&gt;
Puis identité, réseau, SSH, mot de passe et certificat interne sont traités.&lt;br /&gt;
Les phases métier non demandées sont ignorées explicitement.&lt;br /&gt;
&lt;br /&gt;
=== Attente réseau pendant l&#039;isolation ===&lt;br /&gt;
&lt;br /&gt;
Le journal MERCURE3 transmis montre wait-online en attente 120 secondes avant&lt;br /&gt;
activation des carriers ; le réseau est ensuite online sur les deux cartes.&lt;br /&gt;
Le lot ajoute une dispense conditionnelle liée à l&#039;UUID pendant l&#039;isolation,&lt;br /&gt;
dès que QGA est disponible. Les phases first-boot et system l&#039;installent après&lt;br /&gt;
les confirmations et gardes ; network-enable la retire après ses contrôles&lt;br /&gt;
puis vérifie le fonctionnement normal de wait-online avant onboot.&lt;br /&gt;
Le repli réseau remet la dispense après réisolation. Pas de mask/disable,&lt;br /&gt;
pas de changement Netplan optional ou de TEMPLATE3. Les simulations n&#039;écrivent&lt;br /&gt;
aucun fichier. Ce correctif reste à recetter sur un clone ; il ne nécessite&lt;br /&gt;
pas de reconstruire la VM actuelle pour continuer les étapes métier.&lt;br /&gt;
Voir CORRECTIF-WAIT-ONLINE.txt pour les deux fichiers gérés, limites et reprise.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /etc/ajlsm/deploy/projets/mercure3-initial.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les confirmations OUI/NON, défaut NON, et saisies natives restent interactives.&lt;br /&gt;
Pas d&#039;arrêt entre commandes réussies ; arrêt au premier refus ou erreur.&lt;br /&gt;
--agent-timeout est transmis aux phases, défaut 300 secondes, pas un timeout global.&lt;br /&gt;
Après diagnostic, --from reprend l&#039;étape incluse sans refaire les précédentes.&lt;br /&gt;
Un --plan n&#039;exécute rien mais ne garantit ni Proxmox ni l&#039;infrastructure externe.&lt;br /&gt;
&lt;br /&gt;
== NFS : autorisation manuelle guidée ==&lt;br /&gt;
&lt;br /&gt;
Dépôt d&#039;exemples : 192.168.123.202:/var/data/pleade.com-data/data,&lt;br /&gt;
point local identique, mode ro. Un autre dépôt est paramétrable ; plusieurs&lt;br /&gt;
dépôts de MERCURE3 restent une exception manuelle. Le script affiche le fichier&lt;br /&gt;
exports et la ligne à adapter sur Eole3, sans s&#039;y connecter en administrateur.&lt;br /&gt;
L&#039;autorisation de 192.168.123.27 en ro a été réalisée dans la recette.&lt;br /&gt;
Les autres exports et données doivent être conservés. Pas de chmod/chown récursif.&lt;br /&gt;
&lt;br /&gt;
== Apache, Drupal et Pleade ==&lt;br /&gt;
&lt;br /&gt;
Six fichiers gérés sous /etc/apache2/sites-available : HTTP et TLS pour Drupal,&lt;br /&gt;
préprod et Matomo ; fichier robots préprod séparé. Activation par symlinks selon&lt;br /&gt;
le YAML, manifeste, sauvegarde, syntaxe candidate et reload avec tentative de&lt;br /&gt;
restauration locale sur erreur. Une interruption brutale demande un diagnostic.&lt;br /&gt;
Un vhost préparé n&#039;installe pas un logiciel et ne valide pas une application.&lt;br /&gt;
Les fichiers gérés modifiés hors déploiement provoquent un refus, pas un écrasement.&lt;br /&gt;
&lt;br /&gt;
Drupal hérité a été vérifié utilisable avec MariaDB et drupal_template ; son&lt;br /&gt;
vhost principal est actif dans la recette. Pas de personnalisation SQL Drupal&lt;br /&gt;
dédiée dans ce lot. Pleade n&#039;est pas installé, sa préprod reste désactivée ;&lt;br /&gt;
pas d&#039;appel à update.sh. Les futurs slecture et internet ne sont pas publiés.&lt;br /&gt;
&lt;br /&gt;
== Matomo : préparation SQL puis activation coordonnée ==&lt;br /&gt;
&lt;br /&gt;
Base et compte locaux dédiés : matomo_mercure3, sans adoption de matomo_template.&lt;br /&gt;
Configuration préparée root privée dans /var/lib/ajlsm-matomo-sql ; ne pas&lt;br /&gt;
transmettre ces fichiers. En fin de cycle, publication-matomo affiche la pause&lt;br /&gt;
externe, demande une attestation OUI/NON puis active Matomo avec le MÊME YAML.&lt;br /&gt;
Il passe activer=true en mémoire uniquement ; le YAML initial reste intact.&lt;br /&gt;
En mode manuel, après SQL :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3-initial.yaml --matomo-guided-dry-run&lt;br /&gt;
./ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3-initial.yaml --matomo-guided&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L’activation coordonnée conserve Drupal/Pleade. Le mode historique reste&lt;br /&gt;
possible : --with-matomo-site crée une copie d’activation, ensuite utilisée par&lt;br /&gt;
--matomo-site-dry-run puis --matomo-site-apply.&lt;br /&gt;
Ne pas utiliser --apache-apply seul pour cette transition et ne pas relancer&lt;br /&gt;
le clonage avec la copie d&#039;activation. Le module désactive les anciens vhosts&lt;br /&gt;
Matomo connus, sauvegarde le cache, installe la configuration privée et active&lt;br /&gt;
le projet avec contrôle HTTPS local. Les sauvegardes peuvent contenir des secrets.&lt;br /&gt;
&lt;br /&gt;
== Certificats en prérequis et pause avant activation ==&lt;br /&gt;
&lt;br /&gt;
Recommandation : DNS puis challenge ACME stateless prêts, émettre/déployer les&lt;br /&gt;
certificats publics en prérequis, avant même le clonage backend. Le challenge&lt;br /&gt;
HAProxy ne dépend pas de Matomo. Une pause reste obligatoire à publication-matomo&lt;br /&gt;
pour vérifier les certificats et le routage restreint sur LES DEUX nœuds.&lt;br /&gt;
NON arrête proprement le cycle ; --resume reprend après préparation externe.&lt;br /&gt;
Aucune commande ACME/Ansible n’est exécutée par le script et l’attestation&lt;br /&gt;
humaine ne constitue pas une vérification automatisée.&lt;br /&gt;
&lt;br /&gt;
Le certificat interne généré dans le clone n&#039;est pas le certificat public.&lt;br /&gt;
Les certificats publics sont vérifiés/générés avec acme.sh sous l&#039;utilisateur&lt;br /&gt;
acme sur les deux HAProxy, l&#039;un après l&#039;autre. Connexion hpr puis sudo -i,&lt;br /&gt;
pas root SSH. Conserver le challenge HTTP-01 stateless avant la whitelist.&lt;br /&gt;
Émission et déploiement Matomo ont réussi sur les deux nœuds lors de la recette.&lt;br /&gt;
Un certificat valide pour le même domaine n&#039;est pas à refaire parce que le&lt;br /&gt;
backend est recréé ; revérifier validité, déploiement et renouvellement.&lt;br /&gt;
&lt;br /&gt;
Ansible ajoute ACL du domaine, refus hors whitelist, redirection HTTPS et&lt;br /&gt;
backend SNI vers 10.0.0.43:443. Matomo interne MERCURE3 : allowed_ajlsm uniquement.&lt;br /&gt;
Pour un client, prévoir AJLSM et whitelist client selon les règles préprod.&lt;br /&gt;
Le backend conserve ssl verify none : l&#039;identité du backend n&#039;est pas validée.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml --syntax-check&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml --limit haproxy01.ajlsm.lan --check --diff&lt;br /&gt;
ansible-playbook -i inventory ./plays/deploy.haproxy.yml --limit haproxy02.ajlsm.lan --check --diff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Examiner tous les diffs puis appliquer séparément en retirant --check, attendre&lt;br /&gt;
le succès du premier nœud avant le second. Aucun lancement Ansible automatique&lt;br /&gt;
depuis Proxmox. Le check-mode n&#039;est pas l&#039;application réelle.&lt;br /&gt;
Recette transmise : deux applications réussies, validation et restart signalés,&lt;br /&gt;
aucun failed/unreachable. Avertissement Python découvert /usr/bin/python3.10,&lt;br /&gt;
non bloquant dans ces exécutions. Aucun changement d&#039;interpréteur ici.&lt;br /&gt;
&lt;br /&gt;
Tester HTTPS sans -k depuis l&#039;IP autorisée puis hors whitelist. Résultats&lt;br /&gt;
transmis : 200 avec en-tête Matomo via VPN bureau, 403 hors whitelist.&lt;br /&gt;
Un HTTP 200 n&#039;est pas une validation d&#039;installation fonctionnelle.&lt;br /&gt;
&lt;br /&gt;
== Tâches planifiées : correction ciblée puis audit ==&lt;br /&gt;
&lt;br /&gt;
--scheduled-audit inventorie crontabs root/ajlsm/www-data, fichiers système,&lt;br /&gt;
noms des scripts périodiques, timers systemd et instances Tomcat. Les commandes&lt;br /&gt;
et arguments privés ne sont pas affichés. L&#039;audit historique et l&#039;inventaire&lt;br /&gt;
avant traitement confirment 13 lignes Tomcat et trois processus, sans Pleade détecté.&lt;br /&gt;
Après cycle du 18 octobre : zéro tâche Tomcat active pour les trois instances&lt;br /&gt;
vides ; processus déjà lancés conservés et archivage mensuel inchangé.&lt;br /&gt;
Les tâches des autres comptes, timers utilisateurs et contenus des scripts&lt;br /&gt;
restent hors audit. L&#039;inventaire seul n&#039;effectue aucune désactivation.&lt;br /&gt;
Code 0 = inventaire obtenu, pas tâches approuvées. Rotation des logs inchangée.&lt;br /&gt;
&lt;br /&gt;
La phase &#039;&#039;&#039;tomcat-cron&#039;&#039;&#039; a été autorisée pour ne pas reproduire ces tâches&lt;br /&gt;
inutiles sur les nouveaux clones. --scheduled-dry-run affiche les lignes&lt;br /&gt;
reconnues à commenter ; --scheduled-apply demande OUI/NON, sauvegarde la crontab&lt;br /&gt;
ajlsm et commente ces seules lignes avec un marqueur réversible. Elle ne lance&lt;br /&gt;
aucune commande de démarrage, arrêt ou nettoyage Tomcat. Le cycle l&#039;exécute en&lt;br /&gt;
étape 15, puis audite le résultat en étape 16.&lt;br /&gt;
&lt;br /&gt;
Critères conservateurs : répertoire Pleade présent et entièrement vide,&lt;br /&gt;
webapps absent d&#039;autre application et lien pleade vers le chemin attendu,&lt;br /&gt;
pas de contexte externe dans conf/Catalina/localhost. Une implantation non&lt;br /&gt;
vérifiable ou un contenu partiel conserve les tâches. Une commande inconnue&lt;br /&gt;
visant une instance vide bloque la phase, sans modification partielle.&lt;br /&gt;
Seules les formes exactes des commandes héritées auditées sont reconnues.&lt;br /&gt;
&lt;br /&gt;
Sauvegarde privée : /var/backups/ajlsm-scheduled/transaction-* ; journal :&lt;br /&gt;
/var/lib/ajlsm-scheduled/transaction.json. Vérification identité/UUID et&lt;br /&gt;
empreinte de la crontab avant application, relecture après installation.&lt;br /&gt;
Restauration tentée sur erreur contrôlée si elle n&#039;écrase pas un changement&lt;br /&gt;
concurrent détecté. Sinon journal conservé et reprise bloquée pour examen manuel.&lt;br /&gt;
Le verrou ne protège pas contre crontab -e dans un autre terminal : ne pas&lt;br /&gt;
modifier simultanément les tâches ou déployer une application pendant la phase.&lt;br /&gt;
L&#039;interface crontab ne fournit pas de comparaison-installation atomique face&lt;br /&gt;
aux outils extérieurs. Les @reboot des premiers démarrages du clone peuvent&lt;br /&gt;
déjà avoir lancé Tomcat : seuls les lancements futurs sont neutralisés.&lt;br /&gt;
Pas de réactivation automatique lors d&#039;une installation Pleade ultérieure.&lt;br /&gt;
&lt;br /&gt;
== Finalisation fonctionnelle, hors déploiement piloté ==&lt;br /&gt;
&lt;br /&gt;
L&#039;installateur Matomo a confirmé « Tables créées » dans la recette. Création&lt;br /&gt;
du superadministrateur, premier site, fin de l&#039;assistant et intégration du suivi&lt;br /&gt;
restent manuelles. Ne pas laisser un installateur inachevé ouvert durablement.&lt;br /&gt;
Lire FINALISATION-MATOMO.txt : reprise directe tablesCreation et avertissement&lt;br /&gt;
sur systemCheck qui supprime la configuration locale préparée en version auditée.&lt;br /&gt;
Diagnostics applicatifs non annoncés comme faits. Ne pas partager de secrets.&lt;br /&gt;
&lt;br /&gt;
== Point d’arrêt et reprise depuis tout répertoire ==&lt;br /&gt;
&lt;br /&gt;
Le nouveau lanceur conserve un journal privé sur Saturne3 dans&lt;br /&gt;
/var/lib/ajlsm-deploy/cycles/, mode 600, historique par exécution.&lt;br /&gt;
Il n’enregistre ni mots de passe, ni sortie complète des phases.&lt;br /&gt;
Il suit étape courante, dernière réussite, dates UTC, codes de sortie,&lt;br /&gt;
empreintes du YAML/lot, hôte et identité VMID/UUID de la cible.&lt;br /&gt;
Un verrou protège ce journal, pas les interventions d’un autre administrateur.&lt;br /&gt;
&lt;br /&gt;
Avec chemins absolus, depuis n’importe quel répertoire &#039;&#039;&#039;du même nœud&#039;&#039;&#039; :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/ajlsm-deploy/v1/ajlsm-deploy-cycle /etc/ajlsm/deploy/projets/mercure3-initial.yaml --status&lt;br /&gt;
/opt/ajlsm-deploy/v1/ajlsm-deploy-cycle /etc/ajlsm/deploy/projets/mercure3-initial.yaml --resume&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--status ne contacte pas Proxmox et ne crée aucun journal. --resume reprend&lt;br /&gt;
la première étape non réussie, avec contrôles et confirmations habituels.&lt;br /&gt;
Une faute « ouii » à tls se reprend donc à tls sans reclonage.&lt;br /&gt;
La reprise refuse les changements de nœud, YAML, code/ordre ou d’identité&lt;br /&gt;
VM enregistrée. Elle ne relance pas un cycle déjà terminé.&lt;br /&gt;
Après coupure brutale, en_cours signifie résultat inconnu : examiner les&lt;br /&gt;
journaux transactionnels, l’état et les processus avant reprise.&lt;br /&gt;
Le journal n’est pas une preuve de conformité permanente de l’infrastructure.&lt;br /&gt;
&lt;br /&gt;
--from étape reste une reprise explicite après diagnostic, qui démarre un&lt;br /&gt;
nouveau journal et marque les étapes antérieures ignorées, pas vérifiées.&lt;br /&gt;
Ne pas effacer les journaux pour contourner une erreur.&lt;br /&gt;
Les anciens lots sans journal ne permettent pas --resume rétroactif :&lt;br /&gt;
consulter leur sortie console puis reprendre avec --from.&lt;br /&gt;
Pour la VM actuelle, l’application de la dernière simulation Matomo n’est&lt;br /&gt;
pas confirmée. Contrôler avant de reprendre à publication-matomo, sans clonage.&lt;br /&gt;
&lt;br /&gt;
== Détails de sécurité conservés de la documentation du 16 octobre ==&lt;br /&gt;
&lt;br /&gt;
L’audit SSH lit la clé ED25519 via QEMU, vérifie son format binaire, puis&lt;br /&gt;
compare indépendamment celle exposée par ssh-keyscan. Une divergence refuse&lt;br /&gt;
la suite. Après concordance seulement, sauvegarde et remplacement atomique&lt;br /&gt;
possible de /root/.ssh/known_hosts sur Saturne3 ; les autres hôtes sont conservés,&lt;br /&gt;
y compris traitement ciblé des anciennes entrées hachées de l’IP du clone.&lt;br /&gt;
--ssh-audit n’est donc pas entièrement sans écriture.&lt;br /&gt;
--ssh-secure vérifie la syntaxe/effectivité et les connexions par clé avant/après&lt;br /&gt;
reload ; le mot de passe local reste utile à sudo.&lt;br /&gt;
--password-ajlsm utilise passwd interactif masqué ; aucun secret dans le YAML.&lt;br /&gt;
&lt;br /&gt;
La personnalisation système conserve dans la VM&lt;br /&gt;
/var/lib/ajlsm/system-personalisation/state.json et backup/. Ce journal décrit&lt;br /&gt;
une transaction, pas le cycle global. Ne pas l’effacer pour forcer une reprise.&lt;br /&gt;
La phase TLS vérifie le certificat interne /etc/ssl/ajlsm/server.crt, utilise&lt;br /&gt;
si nécessaire /usr/local/sbin/ajlsm-init-tls.sh déjà présent dans le modèle,&lt;br /&gt;
puis contrôle Apache. Cela ne valide pas les applications ou le TLS public.&lt;br /&gt;
Le README applicatif /home/ajlsm/README ne doit pas être remplacé par le&lt;br /&gt;
README-ajlsm-deploy de l’outil. Le document README-TEMPLATE3.txt est proposé&lt;br /&gt;
séparément, pas installé automatiquement.&lt;br /&gt;
&lt;br /&gt;
Validation YAML stricte : clés inconnues/répétées et types incorrects refusés ;&lt;br /&gt;
environnement/tags interne, client, prod, sans doublons ; tags [] admis ;&lt;br /&gt;
entiers positifs, mémoire minimale &amp;lt;= maximale, booléens true/false ;&lt;br /&gt;
interfaces netN/ensN uniques, IPv4/CIDR, loopback /32, DNS sans préfixe.&lt;br /&gt;
Passerelle dans le sous-réseau de son interface et distincte de la VM.&lt;br /&gt;
Serveur, bridge et stockage sont à adapter à l’infrastructure, sans liste&lt;br /&gt;
fermée inventée. Les sections métier sont désormais prises en charge :&lt;br /&gt;
l’interdiction historique d’ajouter metier ne s’applique plus à ce schéma.&lt;br /&gt;
&lt;br /&gt;
== Manuels, reprise et validation du lot ==&lt;br /&gt;
&lt;br /&gt;
Pages section 8 de la version 1.0.2 du 19 octobre : deploy, cycle, yaml, check, resources.&lt;br /&gt;
Lecture locale avec man ./man8/ajlsm-deploy.8 ; sauvegarde et installation&lt;br /&gt;
optionnelle décrites dans INSTALLATION-MANUELS.txt, sans copier les scripts.&lt;br /&gt;
Le lancement définitif se fait dans /opt/ajlsm-deploy/v1, sans copier les&lt;br /&gt;
programmes du nœud dans /usr/local/sbin. La commande invitée&lt;br /&gt;
/usr/local/sbin/ajlsm-init-tls.sh reste distincte et n&#039;est pas déplacée.&lt;br /&gt;
Conserver le lot complet, modules et modèles, sans mélanger les versions.&lt;br /&gt;
Une installation du lot ne remplace pas une recette complète sur Proxmox.&lt;br /&gt;
Tests locaux sous tests/, résultats dans RAPPORT-TESTS.txt ; QGA, SQL, PHP&lt;br /&gt;
et services simulés. Ils ne prouvent pas la réussite d&#039;un déploiement distant.&lt;br /&gt;
Une restauration de phase n&#039;annule pas SQL ni les actions web ultérieures.&lt;br /&gt;
Ne pas effacer un journal transaction.json pour forcer une reprise.&lt;br /&gt;
&lt;br /&gt;
== Réconciliation de la page reçue du 16 octobre et état de recette ==&lt;br /&gt;
&lt;br /&gt;
Cette procédure remplace les indications historiques « 11 étapes »,&lt;br /&gt;
« NFS/Apache/Matomo hors cycle » et « aucun journal global ». Le nouveau lot&lt;br /&gt;
compte 17 étapes avec publication protégée, mais la finalisation fonctionnelle&lt;br /&gt;
Matomo reste indépendante. L’ancien man reproduit intégralement dans la page&lt;br /&gt;
du 16 octobre n’est pas recopié ici : les cinq sources man8 de ce lot sont&lt;br /&gt;
la référence de version, sans procédure concurrente.&lt;br /&gt;
Les anciens chemins du 16 octobre restent des archives, pas le lot courant.&lt;br /&gt;
&lt;br /&gt;
Le cycle 16 étapes du lot consolide-taches a été exécuté sur un clone recréé&lt;br /&gt;
le 18 octobre, reprise TLS après faute de saisie incluse. Hostname et racine&lt;br /&gt;
ext4 97 Gio confirmés. Tâches Tomcat neutralisées pour les instances vides ;&lt;br /&gt;
les processus déjà lancés n’ont pas été arrêtés. Le correctif wait-online et&lt;br /&gt;
le nouveau cycle 17 étapes avec journal restent à valider sur Proxmox.&lt;br /&gt;
Les tests locaux ne sont pas une nouvelle recette distante.&lt;br /&gt;
La capture « Tables créées » et la première activation Matomo concernent le&lt;br /&gt;
clone antérieur : ne pas les attribuer automatiquement au clone actuel.&lt;br /&gt;
Le succès nominal ne valide pas le repli réseau après panne.&lt;br /&gt;
&lt;br /&gt;
Le modèle TEMPLATE3 n’a pas été modifié par ces scripts. Cela ne démontre&lt;br /&gt;
pas l’absence de toute autre intervention. Sa mise à jour OS demandée est&lt;br /&gt;
une maintenance à réaliser/valider séparément avant le prochain clonage.&lt;br /&gt;
Aucun nettoyage serveur ni envoi SVN n’est exécuté par cette livraison.&lt;br /&gt;
&lt;br /&gt;
[[Category:Proxmox]][[Category:AJLSM]][[Category:Déploiement]]&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=D%C3%A9ploiement_technique_d%E2%80%99une_VM_AJLSM&amp;diff=6498</id>
		<title>Déploiement technique d’une VM AJLSM</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=D%C3%A9ploiement_technique_d%E2%80%99une_VM_AJLSM&amp;diff=6498"/>
		<updated>2026-10-16T16:40:28Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : /* 11.3. Page man */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= AJLSM-DEPLOY — Déploiement automatisé des VM Proxmox =&lt;br /&gt;
&lt;br /&gt;
Document consolidé au 16 octobre 2026. Cette procédure réunit la page du 15 octobre et la recette actuelle. Elle remplace leurs indications opérationnelles divergentes. L’original du 15 octobre reste archivé séparément.&lt;br /&gt;
&lt;br /&gt;
Référence technique : scripts reçus de Saturne3, puis lot de recette avec lanceur du cycle et assistant YAML.&lt;br /&gt;
&lt;br /&gt;
== 1. Périmètre et résultat de la recette ==&lt;br /&gt;
&lt;br /&gt;
Le cycle technique a été exécuté sur MERCURE3 sans erreur signalée. Les vérifications finales transmises confirment :&lt;br /&gt;
* connexion SSH avec le compte ajlsm ;&lt;br /&gt;
* élévation sudo avec le mot de passe défini pendant le cycle ;&lt;br /&gt;
* hostname mercure3.ajlsm.com ;&lt;br /&gt;
* volume racine ext4 de 97 Gio, dont 85 Gio disponibles lors du contrôle.&lt;br /&gt;
&lt;br /&gt;
Le cycle couvre le clonage, les ressources, l’initialisation du clone, l’extension de la racine, l’identité système, le réseau, SSH, le mot de passe et le certificat TLS interne.&lt;br /&gt;
&lt;br /&gt;
NFS, les configurations applicatives Apache2, Pleade, Drupal et Matomo ne font pas encore partie de ce cycle. Certains logiciels peuvent déjà être présents dans le modèle : leur présence ne constitue pas une configuration applicative du projet.&lt;br /&gt;
&lt;br /&gt;
== 2. Où exécuter les commandes ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Machine !! Rôle !! Exemple d’invite&lt;br /&gt;
|-&lt;br /&gt;
| Mac de l’administrateur || Transfert des archives par scp || Invite locale du Mac&lt;br /&gt;
|-&lt;br /&gt;
| Saturne3 || Préparation YAML, scripts Proxmox et cycle || root@Saturne3&lt;br /&gt;
|-&lt;br /&gt;
| MERCURE3 || Vérifications dans la VM || ajlsm@mercure3 ou root@mercure3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les scripts de déploiement sont exécutés sur Saturne3, pas dans MERCURE3.&lt;br /&gt;
Après « ssh ajlsm@10.0.0.43 », attendre l’invite de la VM avant de saisir les commandes suivantes.&lt;br /&gt;
Pour revenir de root@mercure3 à Saturne3 : un exit quitte sudo, puis un second exit ferme SSH.&lt;br /&gt;
&lt;br /&gt;
== 3. Organisation des fichiers ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/root/ajlsm-deploy/&lt;br /&gt;
  archives/                         Archives reçues, conservées comme références&lt;br /&gt;
  recettes/20261016/&lt;br /&gt;
    ajlsm-deploy-cycle/             Lot technique validé et assistant ajouté&lt;br /&gt;
    ajlsm-deploy-assistant/         Distribution de l’assistant et tests&lt;br /&gt;
    ajlsm-deploy-documentation/     Présent guide et modèles YAML&lt;br /&gt;
&lt;br /&gt;
/etc/ajlsm/deploy/projets/mercure3.yaml   Configuration actuellement utilisée&lt;br /&gt;
/usr/local/sbin/                        Scripts installés antérieurement&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le lot de recette contient ajlsm-deploy, ajlsm-deploy-check, ajlsm-deploy-resources, ajlsm-deploy-cycle et les modules ajlsm_deploy_common.py, ajlsm_deploy_rootgrow.py et ajlsm_deploy_postconfig.py. L’assistant ajlsm-deploy-yaml a été ajouté à ce même dossier.&lt;br /&gt;
&lt;br /&gt;
Conserver exécutables et modules ensemble. Utiliser les chemins ./ depuis le dossier de recette pour ne pas appeler une ancienne version de /usr/local/sbin.&lt;br /&gt;
Les anciennes archives « ajlsm-deploy-revise » et « correction-suggestions » ne sont pas la référence courante : elles précèdent les phases supplémentaires reçues dans l’archive serveur.&lt;br /&gt;
&lt;br /&gt;
Prérequis : Python 3.9 ou supérieur, PyYAML 6, outils Proxmox sur le nœud cible et prérequis du modèle AJLSM. Les phases invitées utilisent notamment l’agent QEMU, ajlsm-clone-init, Python, systemd et Netplan. L’extension actuelle cible ext4/LVM sur /dev/sda3, avec un seul PV et un seul LV.&lt;br /&gt;
&lt;br /&gt;
== 4. Les deux fichiers de préconfiguration ==&lt;br /&gt;
&lt;br /&gt;
=== 4.1. projet-vierge.yaml ===&lt;br /&gt;
&lt;br /&gt;
Ce modèle reprend toute la structure actuelle sans valeur opérationnelle préremplie. Chaque champ doit être renseigné. Seul proxmox.vmid peut rester null : il signifie alors attribution automatique.&lt;br /&gt;
&lt;br /&gt;
Le modèle comporte deux interfaces dont les valeurs sont null. Adapter le nombre d’interfaces avant la saisie si nécessaire. Pour déterminer ce nombre par les questions de l’assistant, utiliser plutôt le mode --new.&lt;br /&gt;
&lt;br /&gt;
Un modèle vierge est volontairement refusé par --check. Il ne doit jamais être passé directement au lanceur du cycle.&lt;br /&gt;
&lt;br /&gt;
=== 4.2. mercure3-reference.yaml ===&lt;br /&gt;
&lt;br /&gt;
Ce fichier conserve les valeurs du projet validé : modèle 506 sur Saturne3, nom MERCURE3, 8 vCPU, 24576 Mio de RAM maximale, 16384 Mio minimale, disque 100 Gio, extension racine activée et paramètres réseau du projet.&lt;br /&gt;
&lt;br /&gt;
Il permet de reconstruire une nouvelle VM avec la même configuration technique si le modèle, le stockage, les bridges et les préparatifs externes sont toujours disponibles. Il ne sauvegarde ni les données de l’ancienne VM, ni ses UUID, machine-id, clés hôte SSH ou mots de passe. Ces identités sont traitées par le cycle et ne sont pas à recopier.&lt;br /&gt;
&lt;br /&gt;
Avec vmid: null, le VMID de remplacement peut différer de celui de l’ancienne VM. Le VMID 505 observé pendant la recette n’est pas une réservation permanente.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ne pas lancer cette référence tant que MERCURE3 existe encore.&#039;&#039;&#039; Le clonage refuse un nom déjà présent. Pour tester une deuxième VM en parallèle, définir un autre nom, hostname, des IP distinctes et préparer DNS/OPNsense/Ansible en conséquence.&lt;br /&gt;
&lt;br /&gt;
=== 4.3. Valeurs acceptées ===&lt;br /&gt;
&lt;br /&gt;
* projet.environnement et tags : interne, client, prod. Les tags sont une liste sans doublons ; [] est admis.&lt;br /&gt;
* CPU, mémoire et taille du disque : entiers strictement positifs ; mémoire minimale inférieure ou égale à la maximale.&lt;br /&gt;
* Booléens : utiliser true ou false sans guillemets.&lt;br /&gt;
* Interfaces Proxmox : net suivi de chiffres ; interfaces invitées : ens suivi de chiffres.&lt;br /&gt;
* Adresses d’interfaces : IPv4/CIDR. Loopback : IPv4/32. Passerelle et DNS : IPv4 sans préfixe.&lt;br /&gt;
* Passerelle : interface déclarée et adresse appartenant à son sous-réseau, distincte des adresses de la VM.&lt;br /&gt;
* Hostname : nom DNS en minuscules.&lt;br /&gt;
* Serveur, bridge et stockage : valeurs adaptées à l’infrastructure ; aucune liste fermée inventée.&lt;br /&gt;
&lt;br /&gt;
Les clés inconnues ou répétées sont refusées. Ne pas ajouter de sections applicatives avant l’évolution coordonnée du schéma et des scripts. Ne pas utiliser [à renseigner] : les crochets créent une liste YAML.&lt;br /&gt;
&lt;br /&gt;
== 5. Préparer et valider le YAML ==&lt;br /&gt;
&lt;br /&gt;
Sur Saturne3, se placer dans le lot de recette :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5.1. Vérifier un fichier existant sans le modifier ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml /etc/ajlsm/deploy/projets/mercure3.yaml --check&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le message de succès signifie que les valeurs et leur cohérence locale sont conformes. Il ne certifie pas la préparation des services externes.&lt;br /&gt;
&lt;br /&gt;
Voici un exemple : &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;projet:&lt;br /&gt;
  code: mercure3&lt;br /&gt;
  nom: MERCURE3&lt;br /&gt;
  environnement: interne&lt;br /&gt;
&lt;br /&gt;
proxmox:&lt;br /&gt;
  serveur: Saturne3&lt;br /&gt;
  template_vmid: 506&lt;br /&gt;
  vmid: null&lt;br /&gt;
  nom_vm: MERCURE3&lt;br /&gt;
&lt;br /&gt;
  cpu:&lt;br /&gt;
    sockets: 1&lt;br /&gt;
    cores: 8&lt;br /&gt;
&lt;br /&gt;
  memoire:&lt;br /&gt;
    maximale_mib: 24576&lt;br /&gt;
    minimale_mib: 16384&lt;br /&gt;
&lt;br /&gt;
  disque_systeme:&lt;br /&gt;
    stockage: local-zfs&lt;br /&gt;
    taille_gib: 100&lt;br /&gt;
    etendre_volume_racine: true&lt;br /&gt;
&lt;br /&gt;
  demarrage_auto: true&lt;br /&gt;
&lt;br /&gt;
  tags:&lt;br /&gt;
    - interne&lt;br /&gt;
&lt;br /&gt;
systeme:&lt;br /&gt;
  hostname: mercure3.ajlsm.com&lt;br /&gt;
&lt;br /&gt;
reseau:&lt;br /&gt;
  interfaces:&lt;br /&gt;
    - nom: net0&lt;br /&gt;
      bridge: vmbr2&lt;br /&gt;
      systeme: ens18&lt;br /&gt;
      ipv4: 10.0.0.43/24&lt;br /&gt;
&lt;br /&gt;
    - nom: net1&lt;br /&gt;
      bridge: vmbr1&lt;br /&gt;
      systeme: ens19&lt;br /&gt;
      ipv4: 192.168.123.27/24&lt;br /&gt;
&lt;br /&gt;
  loopback:&lt;br /&gt;
    ipv4: 51.83.117.113/32&lt;br /&gt;
&lt;br /&gt;
  passerelle:&lt;br /&gt;
    ipv4: 10.0.0.4&lt;br /&gt;
    interface: ens18&lt;br /&gt;
&lt;br /&gt;
  dns:&lt;br /&gt;
    - 10.0.0.4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5.2. Compléter le modèle vierge ===&lt;br /&gt;
&lt;br /&gt;
Après extraction du présent lot documentaire :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml \&lt;br /&gt;
  /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-documentation/projet-vierge.yaml \&lt;br /&gt;
  --output /root/ajlsm-deploy/recettes/20261016/nouveau-projet.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Toutes les valeurs obligatoires seront demandées. Pour saisir de nouveau le projet MERCURE3, consulter mercure3-reference.yaml comme fiche de paramètres, sans lancer de déploiement.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;# Préconfiguration AJLSM vierge : aucune valeur d’infrastructure préremplie.&lt;br /&gt;
# Compléter avec ajlsm-deploy-yaml ; ne pas déployer ce modèle tel quel.&lt;br /&gt;
# null = champ à renseigner, SAUF proxmox.vmid où null = attribution automatique.&lt;br /&gt;
# Les crochets [à renseigner] sont interdits : ils représenteraient une liste YAML.&lt;br /&gt;
# Deux interfaces sont proposées : adapter leur nombre avant la saisie.&lt;br /&gt;
projet:&lt;br /&gt;
  code: null  # Obligatoire : minuscules/chiffres, tiret et souligné ; ex. mercure3.&lt;br /&gt;
  nom: null  # Obligatoire : nom lisible du projet.&lt;br /&gt;
  environnement: null  # Liste fermée : interne, client, prod.&lt;br /&gt;
&lt;br /&gt;
proxmox:&lt;br /&gt;
  serveur: null  # Obligatoire : nom du nœud Proxmox, ex. Saturne3.&lt;br /&gt;
  template_vmid: null  # Obligatoire : entier positif, VM modèle existante et arrêtée.&lt;br /&gt;
  vmid: null  # Automatique ; sinon entier positif différent de template_vmid.&lt;br /&gt;
  nom_vm: null  # Obligatoire : nom de VM, lettres/chiffres/point/tiret.&lt;br /&gt;
  cpu:&lt;br /&gt;
    sockets: null  # Obligatoire : entier positif.&lt;br /&gt;
    cores: null  # Obligatoire : entier positif ; vCPU = sockets × cores.&lt;br /&gt;
  memoire:&lt;br /&gt;
    maximale_mib: null  # Obligatoire : entier positif, en Mio.&lt;br /&gt;
    minimale_mib: null  # Obligatoire : entier positif, inférieur ou égal au maximum.&lt;br /&gt;
  disque_systeme:&lt;br /&gt;
    stockage: null  # Obligatoire : identifiant de stockage Proxmox existant.&lt;br /&gt;
    taille_gib: null  # Obligatoire : entier positif en Gio ; aucune réduction de disque.&lt;br /&gt;
    etendre_volume_racine: null  # Obligatoire : true ou false ; active la phase racine.&lt;br /&gt;
  demarrage_auto: null  # Obligatoire : true ou false ; appliqué à l’activation réseau.&lt;br /&gt;
  tags: null  # Obligatoire : liste ; interne/client/prod uniquement, sans doublons ; [] admis.&lt;br /&gt;
&lt;br /&gt;
systeme:&lt;br /&gt;
  hostname: null  # Obligatoire : nom DNS en minuscules ; vérifier sa déclaration en amont.&lt;br /&gt;
&lt;br /&gt;
reseau:&lt;br /&gt;
  interfaces:&lt;br /&gt;
    - nom: null  # Obligatoire : net suivi de chiffres, conforme à la VM modèle.&lt;br /&gt;
      bridge: null  # Obligatoire : bridge existant, au plus 15 caractères.&lt;br /&gt;
      systeme: null  # Obligatoire : ens suivi de chiffres, conforme au modèle actuel.&lt;br /&gt;
      ipv4: null  # Obligatoire : IPv4/CIDR, ex. 10.0.0.43/24 ; adresse unique.&lt;br /&gt;
    - nom: null&lt;br /&gt;
      bridge: null&lt;br /&gt;
      systeme: null&lt;br /&gt;
      ipv4: null&lt;br /&gt;
  loopback:&lt;br /&gt;
    ipv4: null  # Obligatoire : IPv4 avec préfixe /32, distincte des interfaces.&lt;br /&gt;
  passerelle:&lt;br /&gt;
    ipv4: null  # Obligatoire : IPv4 seule, dans le sous-réseau de son interface.&lt;br /&gt;
    interface: null  # Obligatoire : un des noms systeme déclarés ci-dessus.&lt;br /&gt;
  dns: null  # Obligatoire : liste non vide d’IPv4 sans préfixe, ex. [10.0.0.4].&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5.3. Créer sans modèle ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml /root/ajlsm-deploy/recettes/20261016/nouveau-projet.yaml --new&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette commande est une alternative à la précédente : le chemin doit être inexistant. L’assistant pose les questions, y compris le nombre d’interfaces, sans reprendre implicitement les valeurs de MERCURE3.&lt;br /&gt;
&lt;br /&gt;
=== 5.4. Revoir un projet renseigné ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml /etc/ajlsm/deploy/projets/mercure3.yaml --review \&lt;br /&gt;
  --output /root/ajlsm-deploy/recettes/20261016/mercure3-relecture.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Entrée conserve une valeur existante valide.&lt;br /&gt;
* ANNULER, Ctrl-C ou fin d’entrée abandonnent sans enregistrer.&lt;br /&gt;
* Tags et DNS sont saisis séparés par des virgules ; [] ou aucun signifie tags vides.&lt;br /&gt;
* Saisir auto ou null pour un VMID automatique.&lt;br /&gt;
* Après une incohérence, donner le chemin du champ à corriger ; ? affiche les chemins.&lt;br /&gt;
* Le résumé complet est présenté avant confirmation OUI/NON d’enregistrement.&lt;br /&gt;
&lt;br /&gt;
L’original reste intact, avec ses commentaires. La copie est réécrite en YAML, sans reprise des commentaires. Aucun fichier existant n’est écrasé. Si une destination existe, choisir un nouveau nom avec --output.&lt;br /&gt;
&lt;br /&gt;
=== 5.5. Préparatifs externes ===&lt;br /&gt;
&lt;br /&gt;
Avant une création, vérifier séparément la réservation des IP, les déclarations DNS, les règles/routes/NAT nécessaires dans OPNsense et l’inventaire ou les préparatifs Ansible. Ne pas inscrire de mots de passe dans le YAML ; conserver les secrets dans le dispositif prévu pour leur gestion.&lt;br /&gt;
&lt;br /&gt;
L’assistant actuel ne vérifie pas automatiquement ces services et ne marque pas un projet « prêt à déployer » sur cette seule base. Leur intégration reste à réaliser.&lt;br /&gt;
&lt;br /&gt;
Le contrôle Proxmox autonome examine notamment le modèle, ses ressources, le stockage et les bridges. Il concerne une nouvelle création et peut refuser un projet déjà déployé :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-check /chemin/vers/projet.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 6. Afficher le plan puis lancer le cycle ==&lt;br /&gt;
&lt;br /&gt;
=== 6.1. Plan sans exécution ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /chemin/vers/projet.yaml --plan&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le plan valide le YAML et affiche les commandes, sans exécuter les phases ni vérifier l’infrastructure. Il doit contenir les 11 étapes, toutes dans le dossier de recette.&lt;br /&gt;
&lt;br /&gt;
=== 6.2. Cycle réel pour une nouvelle VM ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /chemin/vers/projet.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le lanceur exécute les phases réelles, sans simulation automatique. Il attend seulement les confirmations, les saisies nécessaires et la fin de chaque commande. Il s’arrête sur refus ou erreur. Il ne répond pas à la place de l’administrateur et ne capture pas les mots de passe.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! N° !! Étape !! Commande réelle !! Simulation facultative&lt;br /&gt;
|-&lt;br /&gt;
| 1 || Clonage || --clone || --dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Ressources || --configure-resources || --resources-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Premier démarrage isolé || --first-boot-apply || --first-boot-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Extension partition/LVM/ext4 || --root-grow-apply || --root-grow-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Identité système || --system-apply || --system-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Préparation Netplan || --network-apply || --network-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Activation réseau || --network-enable || --network-enable-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Audit SSH || --ssh-audit || Aucune option dédiée&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Sécurisation SSH || --ssh-secure || Aucune option dédiée&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Mot de passe ajlsm || --password-ajlsm || Aucune option dédiée&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Certificat TLS interne || --tls-apply || Aucune option dédiée&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
L’extension racine est indispensable quand etendre_volume_racine vaut true. Agrandir le disque Proxmox ne suffit pas : la partition, le PV LVM, le LV et ext4 doivent aussi être étendus. Cette phase doit figurer après le premier démarrage, avant la personnalisation système. Avec false, la phase annonce sa désactivation.&lt;br /&gt;
&lt;br /&gt;
Le démarrage et la personnalisation se font réseau isolé. Netplan est préparé avant activation des liens. La phase d’activation contrôle le réseau et applique demarrage_auto.&lt;br /&gt;
&lt;br /&gt;
Le certificat TLS interne ne constitue pas, à lui seul, une configuration des applications du projet ou un certificat publiquement reconnu.&lt;br /&gt;
&lt;br /&gt;
=== 6.3. Mode manuel ===&lt;br /&gt;
&lt;br /&gt;
Chaque phase peut être lancée séparément avec ./ajlsm-deploy suivi du YAML et de son option. Après succès, le lot courant affiche deux lignes pour l’étape suivante : Simulation et Exécution. Si la simulation n’existe pas, il le signale. Aucune suggestion n’est exécutée automatiquement.&lt;br /&gt;
&lt;br /&gt;
Les simulations peuvent consulter l’invité et émettre des sondes ARP selon la phase : elles ne sont pas toutes des contrôles hors ligne. L’absence de réponse ARP ne remplace pas la réservation des adresses dans l’inventaire réseau.&lt;br /&gt;
&lt;br /&gt;
== 7. Erreur, annulation et reprise ==&lt;br /&gt;
&lt;br /&gt;
Conserver la sortie complète et diagnostiquer la phase fautive avant de reprendre. Une phase peut être partiellement effectuée ; le lanceur n’effectue ni suppression de VM ni restauration globale automatique.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /chemin/vers/projet.yaml --from extension-racine&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--from inclut l’étape indiquée et saute les précédentes à la demande de l’administrateur. Il ne certifie pas leur état. Les contrôles propres aux phases restent actifs. Le lanceur ne possède pas de journal persistant global de progression.&lt;br /&gt;
&lt;br /&gt;
Ne pas relancer le cycle depuis le clonage sur une VM existante pour terminer une étape. Ne pas relancer des étapes déjà terminées uniquement parce qu’une commande manuelle les suggère. Les suggestions suivent l’ordre théorique et ne constituent pas un inventaire de l’état de la VM.&lt;br /&gt;
&lt;br /&gt;
Codes de sortie : 0 succès, 1 annulation, 2 erreur. Le lanceur normalise les autres codes d’échec de ses sous-processus en erreur et ne poursuit pas.&lt;br /&gt;
&lt;br /&gt;
== 8. Vérifications finales ==&lt;br /&gt;
&lt;br /&gt;
Sur Saturne3, avec le VMID réellement annoncé au clonage :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
qm list&lt;br /&gt;
qm status VMID&lt;br /&gt;
qm config VMID&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remplacer VMID par l’identifiant vérifié. Contrôler le nom, les CPU, la RAM, le disque, les liens réseau et onboot selon le YAML.&lt;br /&gt;
&lt;br /&gt;
Depuis Saturne3, ouvrir la connexion et attendre l’invite de la VM :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh ajlsm@10.0.0.43&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dans MERCURE3, saisir sudo -i, attendre l’authentification et l’invite root, puis :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
hostname&lt;br /&gt;
lsblk&lt;br /&gt;
df -hT /&lt;br /&gt;
ip -br addr&lt;br /&gt;
ip route&lt;br /&gt;
resolvectl status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat vérifié pendant la recette : hostname mercure3.ajlsm.com, racine ext4 97 Gio. Les tailles disponibles évoluent avec l’utilisation. Les commandes SSH et TLS du cycle vérifient leurs propres résultats ; compléter par les tests d’accès attendus dans le réseau cible.&lt;br /&gt;
&lt;br /&gt;
== 9. Reconstruire MERCURE3 ultérieurement ==&lt;br /&gt;
&lt;br /&gt;
# Conserver le fichier mercure3-reference.yaml, le lot de scripts validé et l’identification du modèle utilisé.&lt;br /&gt;
# Comparer la référence au YAML effectivement utilisé avant reconstruction ; actualiser les changements d’infrastructure.&lt;br /&gt;
# Identifier et sauvegarder les données à conserver : le YAML n’est pas une sauvegarde de VM.&lt;br /&gt;
# Vérifier explicitement l’identité de l’ancienne VM et traiter séparément son arrêt et sa suppression volontaire. Le cycle ne détruit jamais automatiquement une VM existante.&lt;br /&gt;
# Contrôler DNS, OPNsense, Ansible et les réservations d’IP. Ne pas laisser deux VM actives avec les mêmes adresses.&lt;br /&gt;
# Valider la référence avec --check, afficher le --plan, puis lancer le cycle sur la référence après libération de la cible.&lt;br /&gt;
# Relever le nouveau VMID et effectuer les vérifications finales.&lt;br /&gt;
&lt;br /&gt;
On retrouve ainsi les paramètres de la VM, sans chercher à reproduire ses anciennes identités techniques.&lt;br /&gt;
&lt;br /&gt;
== 10. Protections et détails techniques ==&lt;br /&gt;
&lt;br /&gt;
=== 10.1. Isolation, identité et journal de personnalisation ===&lt;br /&gt;
&lt;br /&gt;
Le clone est arrêté après création, avec onboot désactivé et les interfaces isolées. Le premier démarrage s’effectue dans cet état d’isolation. Les phases système et réseau vérifient l’identité de la cible et l’UUID attendu selon leurs contrôles propres.&lt;br /&gt;
&lt;br /&gt;
La personnalisation système conserve dans l’invité :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/var/lib/ajlsm/system-personalisation/state.json&lt;br /&gt;
/var/lib/ajlsm/system-personalisation/backup/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce journal décrit la transaction d’identité, pas l’ensemble du cycle. Ne pas le supprimer pour forcer une nouvelle exécution. Après interruption, conserver les sauvegardes et examiner l’état réel avant reprise.&lt;br /&gt;
&lt;br /&gt;
La VM 515 est signalée comme hors périmètre par la documentation historique. Elle ne fait pas partie de la recette MERCURE3 et ne doit pas être ciblée par cette procédure.&lt;br /&gt;
&lt;br /&gt;
=== 10.2. Audit SSH : lecture dans la VM, écriture possible sur Saturne3 ===&lt;br /&gt;
&lt;br /&gt;
La phase --ssh-audit commence par synchroniser l’identité SSH :&lt;br /&gt;
# Lire la clé publique /etc/ssh/ssh_host_ed25519_key.pub dans la VM via l’agent QEMU.&lt;br /&gt;
# Valider le format ED25519 et sa structure binaire attendue.&lt;br /&gt;
# Lire indépendamment la clé exposée sur le réseau avec ssh-keyscan -T 8 -t ed25519.&lt;br /&gt;
# Comparer les clés : une divergence, une absence ou un format invalide provoque un refus.&lt;br /&gt;
# Après concordance seulement, sauvegarder /root/.ssh/known_hosts sur Saturne3, travailler sur une copie et remplacer le fichier avec la nouvelle entrée vérifiée pour l’IP cible.&lt;br /&gt;
# Contrôler les connexions par clé, les clés autorisées, sudo et l’état du compte ajlsm.&lt;br /&gt;
&lt;br /&gt;
Les autres entrées d’hôtes sont conservées ; le traitement retire aussi les anciennes entrées hachées correspondant à l’IP cible. Les sauvegardes utilisent le préfixe known_hosts.ajlsm-backup. dans /root/.ssh/.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;L’audit n’est donc pas entièrement sans écriture :&#039;&#039;&#039; ses lectures dans la VM sont accompagnées d’une mise à jour possible de known_hosts sur Saturne3. Ne jamais contourner une divergence en effaçant aveuglément known_hosts.&lt;br /&gt;
&lt;br /&gt;
=== 10.3. Sécurisation SSH et mot de passe ===&lt;br /&gt;
&lt;br /&gt;
--ssh-secure effectue un audit préalable, prépare un fichier SSH dédié, vérifie la syntaxe et les valeurs effectives, puis recharge SSH. Il désactive l’authentification SSH par mot de passe et conserve root par clé. Les connexions root et ajlsm par clé sont revérifiées par le code reçu.&lt;br /&gt;
&lt;br /&gt;
Le mot de passe local ajlsm reste utile pour sudo. --password-ajlsm utilise un terminal interactif et lance passwd dans la VM, avec sa double saisie masquée. Le secret n’est pas inscrit dans le YAML ni dans la ligne de commande. La procédure historique prévoit un report manuel dans le registre ODS d’administration ; appliquer les règles internes de gestion des secrets. Ne pas joindre ce registre à une documentation publique.&lt;br /&gt;
&lt;br /&gt;
=== 10.4. Certificat TLS interne et Apache ===&lt;br /&gt;
&lt;br /&gt;
--tls-apply lit le certificat /etc/ssl/ajlsm/server.crt. Si le CN et le SAN correspondent déjà au hostname attendu, la phase termine sans réinitialisation. Sinon, après confirmation, elle appelle /usr/local/sbin/ajlsm-init-tls.sh &#039;&#039;&#039;dans la VM&#039;&#039;&#039;. Ce dernier script doit être présent dans le modèle ; son contenu n’était pas inclus dans l’archive des scripts de déploiement reçue.&lt;br /&gt;
&lt;br /&gt;
Après une initialisation réussie, le module contrôle le certificat, apache2ctl configtest et systemctl is-active apache2. Ce contrôle technique d’Apache ne constitue pas une recette des VirtualHosts et des applications du projet.&lt;br /&gt;
&lt;br /&gt;
La documentation historique désigne /home/ajlsm/README, hérité de TEMPLATE3, comme README applicatif Pleade/Drupal. Le conserver séparément du README-ajlsm-deploy de l’outil de déploiement ; ne pas remplacer l’un par l’autre.&lt;br /&gt;
&lt;br /&gt;
=== 10.5. Attente réseau au premier démarrage ===&lt;br /&gt;
&lt;br /&gt;
La recette du 15 octobre signalait environ 60 secondes d’attente dans systemd-networkd-wait-online lorsque les interfaces étaient isolées. Ce constat historique n’a pas empêché l’agent QEMU ni ajlsm-clone-init de répondre. Une optimisation éventuelle du modèle reste distincte du déploiement ; ne pas désactiver le service sans vérifier ses dépendances.&lt;br /&gt;
&lt;br /&gt;
== 11. Maintenance, sauvegardes et manuel ==&lt;br /&gt;
&lt;br /&gt;
=== 11.1. Identifier les fichiers réellement exécutés ===&lt;br /&gt;
&lt;br /&gt;
La recette du 16 octobre utilise le dossier /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/. Elle ne démontre pas une mise à jour globale de /usr/local/sbin/. Toujours distinguer le lot validé et les programmes installés.&lt;br /&gt;
&lt;br /&gt;
Dans le dossier de recette :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy --help&lt;br /&gt;
./ajlsm-deploy-cycle --help&lt;br /&gt;
./ajlsm-deploy-yaml --help&lt;br /&gt;
python3 -m py_compile ajlsm-deploy ajlsm-deploy-check ajlsm-deploy-resources ajlsm-deploy-cycle ajlsm-deploy-yaml ajlsm_deploy_common.py ajlsm_deploy_rootgrow.py ajlsm_deploy_postconfig.py&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Une compilation vérifie la syntaxe, pas le bon déroulement d’une phase ni les prérequis serveur.&lt;br /&gt;
&lt;br /&gt;
=== 11.2. Sauvegarder et restaurer un lot cohérent ===&lt;br /&gt;
&lt;br /&gt;
Conserver ensemble programmes, modules et configuration de référence. Sauvegarder le lot complet avant une installation ou une correction. Exemple sur Saturne3 :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
tar -czf &amp;quot;/root/ajlsm-deploy/archives/lot-recette-$(date +%Y%m%d-%H%M%S).tar.gz&amp;quot; \&lt;br /&gt;
  -C /root/ajlsm-deploy/recettes/20261016 ajlsm-deploy-cycle&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Une restauration doit porter sur un ensemble compatible. Ne pas réinstaller uniquement ajlsm-deploy.bak-20261015 : ce fichier peut précéder les modules et phases nécessaires. L’ancienne sauvegarde et les répertoires de revue sont des références historiques à inventorier avant nettoyage.&lt;br /&gt;
&lt;br /&gt;
Ne pas supprimer INSTRUCTIONS-TEST.txt ou d’autres fichiers de /root/ajlsm-deploy-review/ sur la seule base de l’ancienne page. Leur archivage et le nettoyage ne font pas partie de cette mise à jour documentaire.&lt;br /&gt;
&lt;br /&gt;
=== 11.3. Page man ===&lt;br /&gt;
&lt;br /&gt;
La page du 15 octobre indique un manuel installé en /usr/local/man/man8/ajlsm-deploy.8 et une sauvegarde hors man8 dans /root/ajlsm-deploy-review/sauvegardes-man/. Ce sont des informations historiques, dont l’état actuel n’a pas été vérifié pendant la recette du 16 octobre.&lt;br /&gt;
&lt;br /&gt;
Pour identifier la page disponible sur Saturne3 :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man -w ajlsm-deploy&lt;br /&gt;
man 8 ajlsm-deploy&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Une page absente ne signifie pas que le script est absent : --help est l’aide intégrée de l’exécutable. Le manuel installé doit être réconcilié avec le cycle et l’assistant avant d’être considéré comme référence de cette version. En attendant, le présent guide et l’aide des fichiers du lot de recette décrivent le fonctionnement courant.&lt;br /&gt;
&lt;br /&gt;
Man le 16/10/2026&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
AJLSM-DEPLOY(8)                                     Administration système                                     AJLSM-DEPLOY(8)&lt;br /&gt;
&lt;br /&gt;
NOM&lt;br /&gt;
       ajlsm-deploy - déployer une VM Proxmox par phases contrôlées&lt;br /&gt;
&lt;br /&gt;
SYNOPSIS&lt;br /&gt;
       ajlsm-deploy projet.yaml PHASE [--agent-timeout secondes]&lt;br /&gt;
       ajlsm-deploy-check projet.yaml [--phase proxmox] [--yaml-only]&lt;br /&gt;
       ajlsm-deploy-resources projet.yaml (--dry-run | --apply)&lt;br /&gt;
&lt;br /&gt;
DESCRIPTION&lt;br /&gt;
       Programme  à  exécuter  sur  le  nœud Proxmox cible, avec les droits administrateur. Chaque invocation traite une seule&lt;br /&gt;
       phase.  Le YAML est validé avant les commandes externes.&lt;br /&gt;
&lt;br /&gt;
       Après succès, les suggestions affichent les commandes de simulation et d&#039;exécution de la prochaine étape, ou de l&#039;étape&lt;br /&gt;
       simulée.  Les étapes sans simulation dédiée le signalent explicitement.  Ces suggestions ne sont jamais  exécutées  au‐&lt;br /&gt;
       tomatiquement.  Elles décrivent l&#039;ordre théorique, sans mémoriser l&#039;état du cycle.&lt;br /&gt;
&lt;br /&gt;
       Pour  enchaîner les onze étapes sans en oublier, utiliser ajlsm-deploy-cycle(8).  Ce lanceur conserve les confirmations&lt;br /&gt;
       et les saisies interactives.&lt;br /&gt;
&lt;br /&gt;
ORDRE DES PHASES&lt;br /&gt;
       1. --clone&lt;br /&gt;
              Créer le clone complet, désactiver onboot, isoler les interfaces, vérifier l&#039;arrêt et les  adresses  MAC.  Aucun&lt;br /&gt;
              démarrage.  Simulation : --dry-run, qui comprend les précontrôles.&lt;br /&gt;
&lt;br /&gt;
       2. --configure-resources&lt;br /&gt;
              Configurer  et vérifier CPU, mémoire, balloon et disque scsi0.  Exige une VM arrêtée, onboot désactivé et inter‐&lt;br /&gt;
              faces isolées.  La réduction du disque est interdite.  Simulation : --resources-dry-run.&lt;br /&gt;
&lt;br /&gt;
       3. --first-boot-apply&lt;br /&gt;
              Démarrer le clone isolé, attendre l&#039;agent QEMU et ajlsm-clone-init, puis vérifier les identités  attendues.   Si&lt;br /&gt;
              la VM tourne déjà, reprendre les contrôles sans redémarrage.  Simulation : --first-boot-dry-run.&lt;br /&gt;
&lt;br /&gt;
       4. --root-grow-apply&lt;br /&gt;
              Après  le  premier démarrage et avant la personnalisation système, étendre la partition, le PV LVM, le LV racine&lt;br /&gt;
              et ext4.  Cette étape dépend de etendre_volume_racine dans le YAML.  Simulation : --root-grow-dry-run.&lt;br /&gt;
&lt;br /&gt;
       5. --system-apply&lt;br /&gt;
              Personnaliser hostname, hosts et machine-id, redémarrer isolé et vérifier l&#039;identité active. Respecter le  jour‐&lt;br /&gt;
              nal de transaction.  Simulation : --system-dry-run.&lt;br /&gt;
&lt;br /&gt;
       6. --network-apply&lt;br /&gt;
              Sauvegarder  et  écrire Netplan dans l&#039;invité, puis exécuter netplan generate. Les liens Proxmox restent isolés.&lt;br /&gt;
              Simulation : --network-dry-run.&lt;br /&gt;
&lt;br /&gt;
       7. --network-enable&lt;br /&gt;
              Contrôler identité, configuration et conflits ARP, activer les liens, vérifier adresses, loopback, route, DNS et&lt;br /&gt;
              passerelle, puis appliquer demarrage_auto.  Un mécanisme de repli tente de rétablir l&#039;isolation en cas  d&#039;échec.&lt;br /&gt;
              Simulation : --network-enable-dry-run.&lt;br /&gt;
&lt;br /&gt;
       8. --ssh-audit&lt;br /&gt;
              Comparer  la  clé  ED25519 lue via QEMU à celle exposée sur le réseau, actualiser known_hosts après concordance,&lt;br /&gt;
              puis vérifier les accès, clés autorisées, sudo et état du compte ajlsm.  Aucune simulation dédiée.&lt;br /&gt;
&lt;br /&gt;
       9. --ssh-secure&lt;br /&gt;
              Après audit et confirmation, désactiver l&#039;authentification SSH par mot de passe, conserver root par  clé,  véri‐&lt;br /&gt;
              fier  la  configuration,  recharger  SSH  et  contrôler les connexions root et ajlsm par clé.  Aucune simulation&lt;br /&gt;
              dédiée.&lt;br /&gt;
&lt;br /&gt;
       10. --password-ajlsm&lt;br /&gt;
              Ouvrir passwd pour ajlsm dans la VM avec double saisie native masquée.  Un terminal interactif est  obligatoire.&lt;br /&gt;
              Le mot de passe n&#039;est pas placé dans le YAML ni la ligne de commande.  Aucune simulation dédiée.&lt;br /&gt;
&lt;br /&gt;
       11. --tls-apply&lt;br /&gt;
              Vérifier  le  certificat TLS interne. Si CN et SAN correspondent déjà au hostname, ne pas réinitialiser.  Sinon,&lt;br /&gt;
              après confirmation, appeler ajlsm-init-tls.sh dans la VM, puis vérifier certificat, syntaxe  Apache  et  service&lt;br /&gt;
              actif.  Aucune simulation dédiée.&lt;br /&gt;
&lt;br /&gt;
OPTIONS COMMUNES&lt;br /&gt;
       --agent-timeout secondes&lt;br /&gt;
              Entier  strictement  positif,  défaut 300.  Délai transmis aux attentes utilisant l&#039;agent QEMU.  Il ne constitue&lt;br /&gt;
              pas un délai maximal global.  La phase d&#039;extension racine autorise au moins 600 secondes pour son exécution  in‐&lt;br /&gt;
              vitée après les précontrôles.&lt;br /&gt;
&lt;br /&gt;
       -h, --help&lt;br /&gt;
              Afficher l&#039;aide intégrée sans accéder à Proxmox.&lt;br /&gt;
&lt;br /&gt;
       Choisir  exactement une phase. Les noms des options du programme principal doivent être écrits en entier ; les abrévia‐&lt;br /&gt;
       tions telles que --network-dry sont refusées.&lt;br /&gt;
&lt;br /&gt;
CONFIRMATIONS&lt;br /&gt;
       Seul OUI, sans distinction de casse et après suppression des espaces périphériques, autorise une opération à  la  ques‐&lt;br /&gt;
       tion correspondante.  NON, vide, autre réponse, EOF ou interruption pendant la question annulent. Il n&#039;existe pas d&#039;op‐&lt;br /&gt;
       tion de confirmation automatique.  Une étape déjà conforme peut terminer sans modification ni nouvelle confirmation.&lt;br /&gt;
&lt;br /&gt;
EXTENSION RACINE&lt;br /&gt;
       Le  disque  Proxmox  agrandi  par  la phase ressources ne suffit pas à agrandir le système de fichiers de l&#039;invité.  La&lt;br /&gt;
       phase racine réalise growpart, pvresize et lvextend avec redimensionnement du système de fichiers.&lt;br /&gt;
&lt;br /&gt;
       Topologie prise en charge : racine ext4, PV /dev/sda3, partition terminale parmi trois partitions de /dev/sda, un  seul&lt;br /&gt;
       PV  et  un seul LV. La taille du disque doit correspondre au YAML. Les outils doivent déjà être présents ; aucun paquet&lt;br /&gt;
       n&#039;est installé par cette phase.&lt;br /&gt;
&lt;br /&gt;
       Si la partition est déjà agrandie, le code saute growpart et poursuit le traitement LVM. Si etendre_volume_racine  vaut&lt;br /&gt;
       false, la phase annonce sa désactivation. Vérifier ensuite lsblk et df -hT /.&lt;br /&gt;
&lt;br /&gt;
SSH ET TLS&lt;br /&gt;
       L&#039;audit  SSH  n&#039;est  pas  intégralement sans écriture : il peut sauvegarder et actualiser /root/.ssh/known_hosts sur le&lt;br /&gt;
       nœud Proxmox après comparaison indépendante des clés QEMU/réseau.  Une divergence provoque un refus ; ne pas  supprimer&lt;br /&gt;
       aveuglément known_hosts pour contourner ce contrôle.&lt;br /&gt;
&lt;br /&gt;
       La  structure  binaire ED25519 est contrôlée avant comparaison.  Une clé absente ou malformée provoque également un re‐&lt;br /&gt;
       fus.  Après concordance, les anciennes entrées de l&#039;IP cible, y compris hachées, sont retirées de la copie de  travail.&lt;br /&gt;
       Les autres hôtes sont conservés et le remplacement est atomique.&lt;br /&gt;
&lt;br /&gt;
       Le  mot de passe local ajlsm reste utile pour sudo même lorsque l&#039;authentification SSH par mot de passe est désactivée.&lt;br /&gt;
       Le conserver selon la procédure interne de gestion des secrets.  La procédure AJLSM prévoit un report  manuel  dans  le&lt;br /&gt;
       registre ODS d&#039;administration ; ne pas inclure ce registre dans le YAML.&lt;br /&gt;
&lt;br /&gt;
       Le  certificat  interne  et le contrôle technique d&#039;Apache ne valident pas les VirtualHosts ni les applications. ajlsm-&lt;br /&gt;
       init-tls.sh doit être présent dans l&#039;invité ; son contenu n&#039;est pas fourni par le lot de scripts du nœud Proxmox.&lt;br /&gt;
&lt;br /&gt;
FORMAT YAML&lt;br /&gt;
       Sections obligatoires : projet, proxmox, systeme et reseau.  Les clés inconnues, répétées ou manquantes sont  refusées.&lt;br /&gt;
       Seul  proxmox.vmid  peut rester null pour une attribution automatique.  Ce VMID n&#039;est pas réservé avant clonage et peut&lt;br /&gt;
       changer.&lt;br /&gt;
&lt;br /&gt;
       projet.environnement et tags acceptent interne, client ou prod.  Les tags forment une liste sans doublon ; []  est  ad‐&lt;br /&gt;
       mis.   Les  ressources  exigent des entiers positifs ; la mémoire minimale ne dépasse pas la maximale. Utiliser true ou&lt;br /&gt;
       false pour les booléens.&lt;br /&gt;
&lt;br /&gt;
       Les chaînes numériques et les booléens ne sont pas convertis en entiers par le validateur. Le VMID explicite doit  être&lt;br /&gt;
       différent du template_vmid. Aucune correspondance automatique n&#039;est imposée entre l&#039;environnement et les tags.&lt;br /&gt;
&lt;br /&gt;
       Hostname DNS en minuscules ; interfaces Proxmox netN et invitées ensN.  Les IPv4 d&#039;interfaces exigent un préfixe CIDR ;&lt;br /&gt;
       la  loopback  exige  /32.  La passerelle est dans le sous-réseau de son interface déclarée.  Les interfaces et adresses&lt;br /&gt;
       sont uniques.  Les DNS forment une liste non vide d&#039;IPv4 sans préfixe.  La passerelle doit différer  des  adresses  des&lt;br /&gt;
       interfaces.   Les adresses réseau et broadcast sont refusées pour les sous-réseaux de préfixe inférieur à 31.  Serveur,&lt;br /&gt;
       stockage et bridge restent des valeurs d&#039;infrastructure à renseigner ; aucune liste  fermée  n&#039;est  inventée  pour  ces&lt;br /&gt;
       champs.&lt;br /&gt;
&lt;br /&gt;
       Préparer  le  fichier  avec  ajlsm-deploy-yaml(8).   projet-vierge.yaml  est volontairement incomplet.  mercure3-refer‐&lt;br /&gt;
       ence.yaml conserve les paramètres de reconstruction, pas les données, secrets ou anciennes identités de la VM.&lt;br /&gt;
&lt;br /&gt;
AUXILIAIRES&lt;br /&gt;
       ajlsm-deploy-check&lt;br /&gt;
              Valider le YAML, puis contrôler le modèle, ses  ressources,  le  stockage  et  les  bridges  pour  une  nouvelle&lt;br /&gt;
              création.   --phase  accepte uniquement proxmox.  --yaml-only effectue seulement la validation locale, sans com‐&lt;br /&gt;
              mande Proxmox. Une VM de projet déjà existante peut faire échouer les contrôles de nouvelle création.&lt;br /&gt;
&lt;br /&gt;
       ajlsm-deploy-resources&lt;br /&gt;
              Configurer les ressources avec --apply, ou simuler avec --dry-run. Ces modes  sont  exclusifs  et  obligatoires.&lt;br /&gt;
              Les  protections sont revérifiées avant chaque écriture.  Le programme refuse notamment une cible modèle ou con‐&lt;br /&gt;
              fondue avec la source, et un VMID explicite incohérent.&lt;br /&gt;
&lt;br /&gt;
PRÉREQUIS&lt;br /&gt;
       Python 3.9 ou supérieur, PyYAML 6, outils Proxmox et outils réseau.  Conserver le principal, ses  deux  auxiliaires  et&lt;br /&gt;
       les  modules  common, rootgrow et postconfig dans le même répertoire.  Les auxiliaires doivent être exécutables et leur&lt;br /&gt;
       Python doit disposer de PyYAML.&lt;br /&gt;
&lt;br /&gt;
       Le modèle arrêté doit disposer de l&#039;agent QEMU, ajlsm-clone-init, Python, systemd, Netplan, outils LVM et outils  d&#039;ex‐&lt;br /&gt;
       tension.  Les phases postréseau nécessitent les accès SSH par clé prévus et le script TLS invité.&lt;br /&gt;
&lt;br /&gt;
FICHIERS&lt;br /&gt;
       /etc/ajlsm/deploy/projets/&lt;br /&gt;
              Configurations des projets.&lt;br /&gt;
&lt;br /&gt;
       /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/&lt;br /&gt;
              Lot de recette validé le 16 octobre 2026.  Utiliser les chemins ./ pour ne pas appeler une ancienne version.&lt;br /&gt;
&lt;br /&gt;
       /usr/local/sbin/&lt;br /&gt;
              Programmes installés antérieurement ; leur mise à jour n&#039;est pas prouvée par le succès du lot de recette.&lt;br /&gt;
&lt;br /&gt;
       /var/lib/ajlsm/system-personalisation/&lt;br /&gt;
              Journal et sauvegardes d&#039;identité dans l&#039;invité.  Ne pas effacer pour forcer une reprise.&lt;br /&gt;
&lt;br /&gt;
LIMITES&lt;br /&gt;
       Les  simulations  ne  sont pas toutes hors ligne : la simulation d&#039;activation réseau émet des sondes ARP.  L&#039;absence de&lt;br /&gt;
       réponse ne garantit pas la disponibilité d&#039;une IP.  Le repli réseau en situation réelle reste à recetter.&lt;br /&gt;
&lt;br /&gt;
       Les validations locales ne certifient pas DNS, OPNsense ou Ansible.   NFS,  VirtualHosts  Apache2,  Pleade,  Drupal  et&lt;br /&gt;
       Matomo restent hors du cycle applicatif actuellement implémenté.&lt;br /&gt;
&lt;br /&gt;
       Le  README  applicatif /home/ajlsm/README hérité du modèle est distinct du README de déploiement. Ne pas remplacer l&#039;un&lt;br /&gt;
       par l&#039;autre.&lt;br /&gt;
&lt;br /&gt;
CODES DE SORTIE&lt;br /&gt;
       0 : succès. 1 : annulation. 2 : erreur.  L&#039;aide quitte avec 0 ; une erreur d&#039;arguments quitte avec 2.&lt;br /&gt;
&lt;br /&gt;
EXEMPLES&lt;br /&gt;
       Depuis le dossier de recette, sur Saturne3 :&lt;br /&gt;
       ./ajlsm-deploy-check projet.yaml --yaml-only&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --dry-run&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --clone&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --resources-dry-run&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --configure-resources&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --first-boot-dry-run&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --first-boot-apply&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --root-grow-dry-run&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --root-grow-apply&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --system-dry-run&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --system-apply&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --network-dry-run&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --network-apply&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --network-enable-dry-run&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --network-enable&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --ssh-audit&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --ssh-secure&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --password-ajlsm&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --tls-apply&lt;br /&gt;
       Les simulations sont facultatives. Le mode manuel exige le contrôle de l&#039;ordre des phases. Pour l&#039;enchaînement guidé :&lt;br /&gt;
       ./ajlsm-deploy-cycle projet.yaml --plan&lt;br /&gt;
       ./ajlsm-deploy-cycle projet.yaml&lt;br /&gt;
       Ne pas relancer un cycle de création sur MERCURE3 déjà déployée.&lt;br /&gt;
&lt;br /&gt;
ÉTAT DE LA RECETTE&lt;br /&gt;
       Le manuel installé reçu portait la date du 15 octobre 2026.  Il décrivait déjà les phases racine, SSH et TLS, mais  pas&lt;br /&gt;
       le nouveau lanceur ni l&#039;assistant YAML.&lt;br /&gt;
&lt;br /&gt;
       Le  16 octobre, les sorties transmises ont confirmé la fin du cycle complet sur MERCURE3. Les vérifications finales ont&lt;br /&gt;
       confirmé SSH, sudo, mercure3.ajlsm.com et une racine ext4 de 97 Gio.  Les scénarios négatifs de clés SSH  étaient  rap‐&lt;br /&gt;
       portés  comme  tests  isolés  du  15 octobre ; ils n&#039;ont pas été rejoués lors de la présente révision documentaire.  Le&lt;br /&gt;
       repli réseau réel reste distinct de cette recette nominale.&lt;br /&gt;
&lt;br /&gt;
VOIR AUSSI&lt;br /&gt;
       ajlsm-deploy-cycle(8), ajlsm-deploy-yaml(8), qm(1), lvm(8).&lt;br /&gt;
&lt;br /&gt;
AJLSM                                                  October 16, 2026                                        AJLSM-DEPLOY(8)&lt;br /&gt;
~&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 12. État des validations et limites ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Date / source !! Vérification !! Portée&lt;br /&gt;
|-&lt;br /&gt;
| 15/10/2026, page historique || Déploiements initiaux jusqu’à l’activation réseau || Résultats historiques conservés ; ne décrivent pas à eux seuls le cycle actuel&lt;br /&gt;
|-&lt;br /&gt;
| 15/10/2026, page historique || Comparaison ED25519, clés divergentes ou malformées, préservation de known_hosts || Tests isolés rapportés dans la documentation reçue, non rejoués lors de cette consolidation&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, tests locaux du lot cycle || Ordre des 11 étapes, arrêt sur refus/erreur, reprise et suggestions || 8 tests réussis, incluant des sous-cas ; sous-processus des phases simulés&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, sorties Saturne3 transmises || Cycle technique complet sur un nouveau clone MERCURE3 || Terminé sans erreur signalée, extension racine incluse&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, sorties invitées transmises || SSH ajlsm, sudo, hostname et racine ext4 || Confirmés ; mercure3.ajlsm.com et 97 Gio pour /&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, tests locaux assistant || Création, correction, copie, validation et annulation || 14 tests réussis, saisies simulées&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, sortie Saturne3 transmise || Assistant --check sur mercure3.yaml || Valeurs YAML valides ; aucune écriture ni validation externe&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, vérification locale des modèles || Modèle vierge complété par l’assistant || Paramètres identiques à la référence MERCURE3 ; original intact&lt;br /&gt;
|-&lt;br /&gt;
| À réaliser || Essai réel du mécanisme de repli après échec d’activation réseau || Non confirmé ; le succès du parcours nominal ne valide pas ce scénario&lt;br /&gt;
|-&lt;br /&gt;
| À réaliser || Vérifications automatiques DNS, OPNsense, Ansible et recette applicative || Hors périmètre actuel&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le message de fin du cycle signifie que ses phases ont retourné un succès. Il ne vaut pas validation des applications ni détection de toutes les défaillances possibles. Conserver les vérifications finales et les limites propres aux phases.&lt;br /&gt;
&lt;br /&gt;
== 13. Réconciliation avec la page du 15 octobre ==&lt;br /&gt;
&lt;br /&gt;
L’original reçu est conservé intégralement dans historique/guide-20261015.mediawiki. Il sert de trace, pas de seconde procédure opérationnelle concurrente.&lt;br /&gt;
&lt;br /&gt;
Le présent document remplace les indications opérationnelles anciennes :&lt;br /&gt;
* confirmations CLONER/APPLIQUER/DEMARRER remplacées par OUI/NON ;&lt;br /&gt;
* parcours manuel seul remplacé par le choix entre mode manuel et cycle interactif ;&lt;br /&gt;
* liste des étapes incluant l’extension racine, SSH, mot de passe et TLS ;&lt;br /&gt;
* extension racine et cycle complet désormais validés sur la recette du 16 octobre ;&lt;br /&gt;
* suggestions manuelles affichant les deux commandes disponibles, sans oublier l’extension racine ;&lt;br /&gt;
* création et relecture du YAML par l’assistant, sans écraser l’original ;&lt;br /&gt;
* ajout du modèle vierge et de la référence MERCURE3 renseignée ;&lt;br /&gt;
* séparation explicite des scripts installés, du lot de recette, du manuel historique et de la future installation.&lt;br /&gt;
&lt;br /&gt;
Les détails encore utiles de l’ancienne page sur l’isolation, les transactions, ED25519, les sauvegardes, le README applicatif et les limites de validation sont repris ci-dessus. Une nouvelle mise à jour fonctionnelle doit modifier cette procédure directement plutôt que superposer une nouvelle section corrective à une ancienne procédure contradictoire.&lt;br /&gt;
&lt;br /&gt;
== 14. Suites prévues ==&lt;br /&gt;
&lt;br /&gt;
Prévoir les paramètres NFS, sites Apache2, Pleade, Drupal et Matomo dans le même YAML lorsque leurs exigences seront définies. Modifier ensemble le schéma, l’assistant, les modèles, les précontrôles, les phases et leur documentation. Documenter les références aux secrets plutôt que leurs valeurs.&lt;br /&gt;
&lt;br /&gt;
L’intégration des contrôles DNS, OPNsense et Ansible précédera une déclaration automatisée de disponibilité du projet. Le modèle actuel ne contient pas encore ces nouvelles sections.&lt;br /&gt;
&lt;br /&gt;
[[Catégorie:Infrastructure]]&lt;br /&gt;
[[Catégorie:Proxmox]]&lt;br /&gt;
[[Catégorie:Déploiement]]&lt;br /&gt;
[[Catégorie:AJLSM]]&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=D%C3%A9ploiement_technique_d%E2%80%99une_VM_AJLSM&amp;diff=6497</id>
		<title>Déploiement technique d’une VM AJLSM</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=D%C3%A9ploiement_technique_d%E2%80%99une_VM_AJLSM&amp;diff=6497"/>
		<updated>2026-10-16T16:39:39Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : /* 11.3. Page man */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= AJLSM-DEPLOY — Déploiement automatisé des VM Proxmox =&lt;br /&gt;
&lt;br /&gt;
Document consolidé au 16 octobre 2026. Cette procédure réunit la page du 15 octobre et la recette actuelle. Elle remplace leurs indications opérationnelles divergentes. L’original du 15 octobre reste archivé séparément.&lt;br /&gt;
&lt;br /&gt;
Référence technique : scripts reçus de Saturne3, puis lot de recette avec lanceur du cycle et assistant YAML.&lt;br /&gt;
&lt;br /&gt;
== 1. Périmètre et résultat de la recette ==&lt;br /&gt;
&lt;br /&gt;
Le cycle technique a été exécuté sur MERCURE3 sans erreur signalée. Les vérifications finales transmises confirment :&lt;br /&gt;
* connexion SSH avec le compte ajlsm ;&lt;br /&gt;
* élévation sudo avec le mot de passe défini pendant le cycle ;&lt;br /&gt;
* hostname mercure3.ajlsm.com ;&lt;br /&gt;
* volume racine ext4 de 97 Gio, dont 85 Gio disponibles lors du contrôle.&lt;br /&gt;
&lt;br /&gt;
Le cycle couvre le clonage, les ressources, l’initialisation du clone, l’extension de la racine, l’identité système, le réseau, SSH, le mot de passe et le certificat TLS interne.&lt;br /&gt;
&lt;br /&gt;
NFS, les configurations applicatives Apache2, Pleade, Drupal et Matomo ne font pas encore partie de ce cycle. Certains logiciels peuvent déjà être présents dans le modèle : leur présence ne constitue pas une configuration applicative du projet.&lt;br /&gt;
&lt;br /&gt;
== 2. Où exécuter les commandes ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Machine !! Rôle !! Exemple d’invite&lt;br /&gt;
|-&lt;br /&gt;
| Mac de l’administrateur || Transfert des archives par scp || Invite locale du Mac&lt;br /&gt;
|-&lt;br /&gt;
| Saturne3 || Préparation YAML, scripts Proxmox et cycle || root@Saturne3&lt;br /&gt;
|-&lt;br /&gt;
| MERCURE3 || Vérifications dans la VM || ajlsm@mercure3 ou root@mercure3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les scripts de déploiement sont exécutés sur Saturne3, pas dans MERCURE3.&lt;br /&gt;
Après « ssh ajlsm@10.0.0.43 », attendre l’invite de la VM avant de saisir les commandes suivantes.&lt;br /&gt;
Pour revenir de root@mercure3 à Saturne3 : un exit quitte sudo, puis un second exit ferme SSH.&lt;br /&gt;
&lt;br /&gt;
== 3. Organisation des fichiers ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/root/ajlsm-deploy/&lt;br /&gt;
  archives/                         Archives reçues, conservées comme références&lt;br /&gt;
  recettes/20261016/&lt;br /&gt;
    ajlsm-deploy-cycle/             Lot technique validé et assistant ajouté&lt;br /&gt;
    ajlsm-deploy-assistant/         Distribution de l’assistant et tests&lt;br /&gt;
    ajlsm-deploy-documentation/     Présent guide et modèles YAML&lt;br /&gt;
&lt;br /&gt;
/etc/ajlsm/deploy/projets/mercure3.yaml   Configuration actuellement utilisée&lt;br /&gt;
/usr/local/sbin/                        Scripts installés antérieurement&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le lot de recette contient ajlsm-deploy, ajlsm-deploy-check, ajlsm-deploy-resources, ajlsm-deploy-cycle et les modules ajlsm_deploy_common.py, ajlsm_deploy_rootgrow.py et ajlsm_deploy_postconfig.py. L’assistant ajlsm-deploy-yaml a été ajouté à ce même dossier.&lt;br /&gt;
&lt;br /&gt;
Conserver exécutables et modules ensemble. Utiliser les chemins ./ depuis le dossier de recette pour ne pas appeler une ancienne version de /usr/local/sbin.&lt;br /&gt;
Les anciennes archives « ajlsm-deploy-revise » et « correction-suggestions » ne sont pas la référence courante : elles précèdent les phases supplémentaires reçues dans l’archive serveur.&lt;br /&gt;
&lt;br /&gt;
Prérequis : Python 3.9 ou supérieur, PyYAML 6, outils Proxmox sur le nœud cible et prérequis du modèle AJLSM. Les phases invitées utilisent notamment l’agent QEMU, ajlsm-clone-init, Python, systemd et Netplan. L’extension actuelle cible ext4/LVM sur /dev/sda3, avec un seul PV et un seul LV.&lt;br /&gt;
&lt;br /&gt;
== 4. Les deux fichiers de préconfiguration ==&lt;br /&gt;
&lt;br /&gt;
=== 4.1. projet-vierge.yaml ===&lt;br /&gt;
&lt;br /&gt;
Ce modèle reprend toute la structure actuelle sans valeur opérationnelle préremplie. Chaque champ doit être renseigné. Seul proxmox.vmid peut rester null : il signifie alors attribution automatique.&lt;br /&gt;
&lt;br /&gt;
Le modèle comporte deux interfaces dont les valeurs sont null. Adapter le nombre d’interfaces avant la saisie si nécessaire. Pour déterminer ce nombre par les questions de l’assistant, utiliser plutôt le mode --new.&lt;br /&gt;
&lt;br /&gt;
Un modèle vierge est volontairement refusé par --check. Il ne doit jamais être passé directement au lanceur du cycle.&lt;br /&gt;
&lt;br /&gt;
=== 4.2. mercure3-reference.yaml ===&lt;br /&gt;
&lt;br /&gt;
Ce fichier conserve les valeurs du projet validé : modèle 506 sur Saturne3, nom MERCURE3, 8 vCPU, 24576 Mio de RAM maximale, 16384 Mio minimale, disque 100 Gio, extension racine activée et paramètres réseau du projet.&lt;br /&gt;
&lt;br /&gt;
Il permet de reconstruire une nouvelle VM avec la même configuration technique si le modèle, le stockage, les bridges et les préparatifs externes sont toujours disponibles. Il ne sauvegarde ni les données de l’ancienne VM, ni ses UUID, machine-id, clés hôte SSH ou mots de passe. Ces identités sont traitées par le cycle et ne sont pas à recopier.&lt;br /&gt;
&lt;br /&gt;
Avec vmid: null, le VMID de remplacement peut différer de celui de l’ancienne VM. Le VMID 505 observé pendant la recette n’est pas une réservation permanente.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ne pas lancer cette référence tant que MERCURE3 existe encore.&#039;&#039;&#039; Le clonage refuse un nom déjà présent. Pour tester une deuxième VM en parallèle, définir un autre nom, hostname, des IP distinctes et préparer DNS/OPNsense/Ansible en conséquence.&lt;br /&gt;
&lt;br /&gt;
=== 4.3. Valeurs acceptées ===&lt;br /&gt;
&lt;br /&gt;
* projet.environnement et tags : interne, client, prod. Les tags sont une liste sans doublons ; [] est admis.&lt;br /&gt;
* CPU, mémoire et taille du disque : entiers strictement positifs ; mémoire minimale inférieure ou égale à la maximale.&lt;br /&gt;
* Booléens : utiliser true ou false sans guillemets.&lt;br /&gt;
* Interfaces Proxmox : net suivi de chiffres ; interfaces invitées : ens suivi de chiffres.&lt;br /&gt;
* Adresses d’interfaces : IPv4/CIDR. Loopback : IPv4/32. Passerelle et DNS : IPv4 sans préfixe.&lt;br /&gt;
* Passerelle : interface déclarée et adresse appartenant à son sous-réseau, distincte des adresses de la VM.&lt;br /&gt;
* Hostname : nom DNS en minuscules.&lt;br /&gt;
* Serveur, bridge et stockage : valeurs adaptées à l’infrastructure ; aucune liste fermée inventée.&lt;br /&gt;
&lt;br /&gt;
Les clés inconnues ou répétées sont refusées. Ne pas ajouter de sections applicatives avant l’évolution coordonnée du schéma et des scripts. Ne pas utiliser [à renseigner] : les crochets créent une liste YAML.&lt;br /&gt;
&lt;br /&gt;
== 5. Préparer et valider le YAML ==&lt;br /&gt;
&lt;br /&gt;
Sur Saturne3, se placer dans le lot de recette :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5.1. Vérifier un fichier existant sans le modifier ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml /etc/ajlsm/deploy/projets/mercure3.yaml --check&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le message de succès signifie que les valeurs et leur cohérence locale sont conformes. Il ne certifie pas la préparation des services externes.&lt;br /&gt;
&lt;br /&gt;
Voici un exemple : &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;projet:&lt;br /&gt;
  code: mercure3&lt;br /&gt;
  nom: MERCURE3&lt;br /&gt;
  environnement: interne&lt;br /&gt;
&lt;br /&gt;
proxmox:&lt;br /&gt;
  serveur: Saturne3&lt;br /&gt;
  template_vmid: 506&lt;br /&gt;
  vmid: null&lt;br /&gt;
  nom_vm: MERCURE3&lt;br /&gt;
&lt;br /&gt;
  cpu:&lt;br /&gt;
    sockets: 1&lt;br /&gt;
    cores: 8&lt;br /&gt;
&lt;br /&gt;
  memoire:&lt;br /&gt;
    maximale_mib: 24576&lt;br /&gt;
    minimale_mib: 16384&lt;br /&gt;
&lt;br /&gt;
  disque_systeme:&lt;br /&gt;
    stockage: local-zfs&lt;br /&gt;
    taille_gib: 100&lt;br /&gt;
    etendre_volume_racine: true&lt;br /&gt;
&lt;br /&gt;
  demarrage_auto: true&lt;br /&gt;
&lt;br /&gt;
  tags:&lt;br /&gt;
    - interne&lt;br /&gt;
&lt;br /&gt;
systeme:&lt;br /&gt;
  hostname: mercure3.ajlsm.com&lt;br /&gt;
&lt;br /&gt;
reseau:&lt;br /&gt;
  interfaces:&lt;br /&gt;
    - nom: net0&lt;br /&gt;
      bridge: vmbr2&lt;br /&gt;
      systeme: ens18&lt;br /&gt;
      ipv4: 10.0.0.43/24&lt;br /&gt;
&lt;br /&gt;
    - nom: net1&lt;br /&gt;
      bridge: vmbr1&lt;br /&gt;
      systeme: ens19&lt;br /&gt;
      ipv4: 192.168.123.27/24&lt;br /&gt;
&lt;br /&gt;
  loopback:&lt;br /&gt;
    ipv4: 51.83.117.113/32&lt;br /&gt;
&lt;br /&gt;
  passerelle:&lt;br /&gt;
    ipv4: 10.0.0.4&lt;br /&gt;
    interface: ens18&lt;br /&gt;
&lt;br /&gt;
  dns:&lt;br /&gt;
    - 10.0.0.4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5.2. Compléter le modèle vierge ===&lt;br /&gt;
&lt;br /&gt;
Après extraction du présent lot documentaire :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml \&lt;br /&gt;
  /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-documentation/projet-vierge.yaml \&lt;br /&gt;
  --output /root/ajlsm-deploy/recettes/20261016/nouveau-projet.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Toutes les valeurs obligatoires seront demandées. Pour saisir de nouveau le projet MERCURE3, consulter mercure3-reference.yaml comme fiche de paramètres, sans lancer de déploiement.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;# Préconfiguration AJLSM vierge : aucune valeur d’infrastructure préremplie.&lt;br /&gt;
# Compléter avec ajlsm-deploy-yaml ; ne pas déployer ce modèle tel quel.&lt;br /&gt;
# null = champ à renseigner, SAUF proxmox.vmid où null = attribution automatique.&lt;br /&gt;
# Les crochets [à renseigner] sont interdits : ils représenteraient une liste YAML.&lt;br /&gt;
# Deux interfaces sont proposées : adapter leur nombre avant la saisie.&lt;br /&gt;
projet:&lt;br /&gt;
  code: null  # Obligatoire : minuscules/chiffres, tiret et souligné ; ex. mercure3.&lt;br /&gt;
  nom: null  # Obligatoire : nom lisible du projet.&lt;br /&gt;
  environnement: null  # Liste fermée : interne, client, prod.&lt;br /&gt;
&lt;br /&gt;
proxmox:&lt;br /&gt;
  serveur: null  # Obligatoire : nom du nœud Proxmox, ex. Saturne3.&lt;br /&gt;
  template_vmid: null  # Obligatoire : entier positif, VM modèle existante et arrêtée.&lt;br /&gt;
  vmid: null  # Automatique ; sinon entier positif différent de template_vmid.&lt;br /&gt;
  nom_vm: null  # Obligatoire : nom de VM, lettres/chiffres/point/tiret.&lt;br /&gt;
  cpu:&lt;br /&gt;
    sockets: null  # Obligatoire : entier positif.&lt;br /&gt;
    cores: null  # Obligatoire : entier positif ; vCPU = sockets × cores.&lt;br /&gt;
  memoire:&lt;br /&gt;
    maximale_mib: null  # Obligatoire : entier positif, en Mio.&lt;br /&gt;
    minimale_mib: null  # Obligatoire : entier positif, inférieur ou égal au maximum.&lt;br /&gt;
  disque_systeme:&lt;br /&gt;
    stockage: null  # Obligatoire : identifiant de stockage Proxmox existant.&lt;br /&gt;
    taille_gib: null  # Obligatoire : entier positif en Gio ; aucune réduction de disque.&lt;br /&gt;
    etendre_volume_racine: null  # Obligatoire : true ou false ; active la phase racine.&lt;br /&gt;
  demarrage_auto: null  # Obligatoire : true ou false ; appliqué à l’activation réseau.&lt;br /&gt;
  tags: null  # Obligatoire : liste ; interne/client/prod uniquement, sans doublons ; [] admis.&lt;br /&gt;
&lt;br /&gt;
systeme:&lt;br /&gt;
  hostname: null  # Obligatoire : nom DNS en minuscules ; vérifier sa déclaration en amont.&lt;br /&gt;
&lt;br /&gt;
reseau:&lt;br /&gt;
  interfaces:&lt;br /&gt;
    - nom: null  # Obligatoire : net suivi de chiffres, conforme à la VM modèle.&lt;br /&gt;
      bridge: null  # Obligatoire : bridge existant, au plus 15 caractères.&lt;br /&gt;
      systeme: null  # Obligatoire : ens suivi de chiffres, conforme au modèle actuel.&lt;br /&gt;
      ipv4: null  # Obligatoire : IPv4/CIDR, ex. 10.0.0.43/24 ; adresse unique.&lt;br /&gt;
    - nom: null&lt;br /&gt;
      bridge: null&lt;br /&gt;
      systeme: null&lt;br /&gt;
      ipv4: null&lt;br /&gt;
  loopback:&lt;br /&gt;
    ipv4: null  # Obligatoire : IPv4 avec préfixe /32, distincte des interfaces.&lt;br /&gt;
  passerelle:&lt;br /&gt;
    ipv4: null  # Obligatoire : IPv4 seule, dans le sous-réseau de son interface.&lt;br /&gt;
    interface: null  # Obligatoire : un des noms systeme déclarés ci-dessus.&lt;br /&gt;
  dns: null  # Obligatoire : liste non vide d’IPv4 sans préfixe, ex. [10.0.0.4].&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5.3. Créer sans modèle ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml /root/ajlsm-deploy/recettes/20261016/nouveau-projet.yaml --new&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette commande est une alternative à la précédente : le chemin doit être inexistant. L’assistant pose les questions, y compris le nombre d’interfaces, sans reprendre implicitement les valeurs de MERCURE3.&lt;br /&gt;
&lt;br /&gt;
=== 5.4. Revoir un projet renseigné ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml /etc/ajlsm/deploy/projets/mercure3.yaml --review \&lt;br /&gt;
  --output /root/ajlsm-deploy/recettes/20261016/mercure3-relecture.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Entrée conserve une valeur existante valide.&lt;br /&gt;
* ANNULER, Ctrl-C ou fin d’entrée abandonnent sans enregistrer.&lt;br /&gt;
* Tags et DNS sont saisis séparés par des virgules ; [] ou aucun signifie tags vides.&lt;br /&gt;
* Saisir auto ou null pour un VMID automatique.&lt;br /&gt;
* Après une incohérence, donner le chemin du champ à corriger ; ? affiche les chemins.&lt;br /&gt;
* Le résumé complet est présenté avant confirmation OUI/NON d’enregistrement.&lt;br /&gt;
&lt;br /&gt;
L’original reste intact, avec ses commentaires. La copie est réécrite en YAML, sans reprise des commentaires. Aucun fichier existant n’est écrasé. Si une destination existe, choisir un nouveau nom avec --output.&lt;br /&gt;
&lt;br /&gt;
=== 5.5. Préparatifs externes ===&lt;br /&gt;
&lt;br /&gt;
Avant une création, vérifier séparément la réservation des IP, les déclarations DNS, les règles/routes/NAT nécessaires dans OPNsense et l’inventaire ou les préparatifs Ansible. Ne pas inscrire de mots de passe dans le YAML ; conserver les secrets dans le dispositif prévu pour leur gestion.&lt;br /&gt;
&lt;br /&gt;
L’assistant actuel ne vérifie pas automatiquement ces services et ne marque pas un projet « prêt à déployer » sur cette seule base. Leur intégration reste à réaliser.&lt;br /&gt;
&lt;br /&gt;
Le contrôle Proxmox autonome examine notamment le modèle, ses ressources, le stockage et les bridges. Il concerne une nouvelle création et peut refuser un projet déjà déployé :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-check /chemin/vers/projet.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 6. Afficher le plan puis lancer le cycle ==&lt;br /&gt;
&lt;br /&gt;
=== 6.1. Plan sans exécution ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /chemin/vers/projet.yaml --plan&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le plan valide le YAML et affiche les commandes, sans exécuter les phases ni vérifier l’infrastructure. Il doit contenir les 11 étapes, toutes dans le dossier de recette.&lt;br /&gt;
&lt;br /&gt;
=== 6.2. Cycle réel pour une nouvelle VM ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /chemin/vers/projet.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le lanceur exécute les phases réelles, sans simulation automatique. Il attend seulement les confirmations, les saisies nécessaires et la fin de chaque commande. Il s’arrête sur refus ou erreur. Il ne répond pas à la place de l’administrateur et ne capture pas les mots de passe.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! N° !! Étape !! Commande réelle !! Simulation facultative&lt;br /&gt;
|-&lt;br /&gt;
| 1 || Clonage || --clone || --dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Ressources || --configure-resources || --resources-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Premier démarrage isolé || --first-boot-apply || --first-boot-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Extension partition/LVM/ext4 || --root-grow-apply || --root-grow-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Identité système || --system-apply || --system-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Préparation Netplan || --network-apply || --network-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Activation réseau || --network-enable || --network-enable-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Audit SSH || --ssh-audit || Aucune option dédiée&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Sécurisation SSH || --ssh-secure || Aucune option dédiée&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Mot de passe ajlsm || --password-ajlsm || Aucune option dédiée&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Certificat TLS interne || --tls-apply || Aucune option dédiée&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
L’extension racine est indispensable quand etendre_volume_racine vaut true. Agrandir le disque Proxmox ne suffit pas : la partition, le PV LVM, le LV et ext4 doivent aussi être étendus. Cette phase doit figurer après le premier démarrage, avant la personnalisation système. Avec false, la phase annonce sa désactivation.&lt;br /&gt;
&lt;br /&gt;
Le démarrage et la personnalisation se font réseau isolé. Netplan est préparé avant activation des liens. La phase d’activation contrôle le réseau et applique demarrage_auto.&lt;br /&gt;
&lt;br /&gt;
Le certificat TLS interne ne constitue pas, à lui seul, une configuration des applications du projet ou un certificat publiquement reconnu.&lt;br /&gt;
&lt;br /&gt;
=== 6.3. Mode manuel ===&lt;br /&gt;
&lt;br /&gt;
Chaque phase peut être lancée séparément avec ./ajlsm-deploy suivi du YAML et de son option. Après succès, le lot courant affiche deux lignes pour l’étape suivante : Simulation et Exécution. Si la simulation n’existe pas, il le signale. Aucune suggestion n’est exécutée automatiquement.&lt;br /&gt;
&lt;br /&gt;
Les simulations peuvent consulter l’invité et émettre des sondes ARP selon la phase : elles ne sont pas toutes des contrôles hors ligne. L’absence de réponse ARP ne remplace pas la réservation des adresses dans l’inventaire réseau.&lt;br /&gt;
&lt;br /&gt;
== 7. Erreur, annulation et reprise ==&lt;br /&gt;
&lt;br /&gt;
Conserver la sortie complète et diagnostiquer la phase fautive avant de reprendre. Une phase peut être partiellement effectuée ; le lanceur n’effectue ni suppression de VM ni restauration globale automatique.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /chemin/vers/projet.yaml --from extension-racine&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--from inclut l’étape indiquée et saute les précédentes à la demande de l’administrateur. Il ne certifie pas leur état. Les contrôles propres aux phases restent actifs. Le lanceur ne possède pas de journal persistant global de progression.&lt;br /&gt;
&lt;br /&gt;
Ne pas relancer le cycle depuis le clonage sur une VM existante pour terminer une étape. Ne pas relancer des étapes déjà terminées uniquement parce qu’une commande manuelle les suggère. Les suggestions suivent l’ordre théorique et ne constituent pas un inventaire de l’état de la VM.&lt;br /&gt;
&lt;br /&gt;
Codes de sortie : 0 succès, 1 annulation, 2 erreur. Le lanceur normalise les autres codes d’échec de ses sous-processus en erreur et ne poursuit pas.&lt;br /&gt;
&lt;br /&gt;
== 8. Vérifications finales ==&lt;br /&gt;
&lt;br /&gt;
Sur Saturne3, avec le VMID réellement annoncé au clonage :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
qm list&lt;br /&gt;
qm status VMID&lt;br /&gt;
qm config VMID&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remplacer VMID par l’identifiant vérifié. Contrôler le nom, les CPU, la RAM, le disque, les liens réseau et onboot selon le YAML.&lt;br /&gt;
&lt;br /&gt;
Depuis Saturne3, ouvrir la connexion et attendre l’invite de la VM :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh ajlsm@10.0.0.43&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dans MERCURE3, saisir sudo -i, attendre l’authentification et l’invite root, puis :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
hostname&lt;br /&gt;
lsblk&lt;br /&gt;
df -hT /&lt;br /&gt;
ip -br addr&lt;br /&gt;
ip route&lt;br /&gt;
resolvectl status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat vérifié pendant la recette : hostname mercure3.ajlsm.com, racine ext4 97 Gio. Les tailles disponibles évoluent avec l’utilisation. Les commandes SSH et TLS du cycle vérifient leurs propres résultats ; compléter par les tests d’accès attendus dans le réseau cible.&lt;br /&gt;
&lt;br /&gt;
== 9. Reconstruire MERCURE3 ultérieurement ==&lt;br /&gt;
&lt;br /&gt;
# Conserver le fichier mercure3-reference.yaml, le lot de scripts validé et l’identification du modèle utilisé.&lt;br /&gt;
# Comparer la référence au YAML effectivement utilisé avant reconstruction ; actualiser les changements d’infrastructure.&lt;br /&gt;
# Identifier et sauvegarder les données à conserver : le YAML n’est pas une sauvegarde de VM.&lt;br /&gt;
# Vérifier explicitement l’identité de l’ancienne VM et traiter séparément son arrêt et sa suppression volontaire. Le cycle ne détruit jamais automatiquement une VM existante.&lt;br /&gt;
# Contrôler DNS, OPNsense, Ansible et les réservations d’IP. Ne pas laisser deux VM actives avec les mêmes adresses.&lt;br /&gt;
# Valider la référence avec --check, afficher le --plan, puis lancer le cycle sur la référence après libération de la cible.&lt;br /&gt;
# Relever le nouveau VMID et effectuer les vérifications finales.&lt;br /&gt;
&lt;br /&gt;
On retrouve ainsi les paramètres de la VM, sans chercher à reproduire ses anciennes identités techniques.&lt;br /&gt;
&lt;br /&gt;
== 10. Protections et détails techniques ==&lt;br /&gt;
&lt;br /&gt;
=== 10.1. Isolation, identité et journal de personnalisation ===&lt;br /&gt;
&lt;br /&gt;
Le clone est arrêté après création, avec onboot désactivé et les interfaces isolées. Le premier démarrage s’effectue dans cet état d’isolation. Les phases système et réseau vérifient l’identité de la cible et l’UUID attendu selon leurs contrôles propres.&lt;br /&gt;
&lt;br /&gt;
La personnalisation système conserve dans l’invité :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/var/lib/ajlsm/system-personalisation/state.json&lt;br /&gt;
/var/lib/ajlsm/system-personalisation/backup/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce journal décrit la transaction d’identité, pas l’ensemble du cycle. Ne pas le supprimer pour forcer une nouvelle exécution. Après interruption, conserver les sauvegardes et examiner l’état réel avant reprise.&lt;br /&gt;
&lt;br /&gt;
La VM 515 est signalée comme hors périmètre par la documentation historique. Elle ne fait pas partie de la recette MERCURE3 et ne doit pas être ciblée par cette procédure.&lt;br /&gt;
&lt;br /&gt;
=== 10.2. Audit SSH : lecture dans la VM, écriture possible sur Saturne3 ===&lt;br /&gt;
&lt;br /&gt;
La phase --ssh-audit commence par synchroniser l’identité SSH :&lt;br /&gt;
# Lire la clé publique /etc/ssh/ssh_host_ed25519_key.pub dans la VM via l’agent QEMU.&lt;br /&gt;
# Valider le format ED25519 et sa structure binaire attendue.&lt;br /&gt;
# Lire indépendamment la clé exposée sur le réseau avec ssh-keyscan -T 8 -t ed25519.&lt;br /&gt;
# Comparer les clés : une divergence, une absence ou un format invalide provoque un refus.&lt;br /&gt;
# Après concordance seulement, sauvegarder /root/.ssh/known_hosts sur Saturne3, travailler sur une copie et remplacer le fichier avec la nouvelle entrée vérifiée pour l’IP cible.&lt;br /&gt;
# Contrôler les connexions par clé, les clés autorisées, sudo et l’état du compte ajlsm.&lt;br /&gt;
&lt;br /&gt;
Les autres entrées d’hôtes sont conservées ; le traitement retire aussi les anciennes entrées hachées correspondant à l’IP cible. Les sauvegardes utilisent le préfixe known_hosts.ajlsm-backup. dans /root/.ssh/.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;L’audit n’est donc pas entièrement sans écriture :&#039;&#039;&#039; ses lectures dans la VM sont accompagnées d’une mise à jour possible de known_hosts sur Saturne3. Ne jamais contourner une divergence en effaçant aveuglément known_hosts.&lt;br /&gt;
&lt;br /&gt;
=== 10.3. Sécurisation SSH et mot de passe ===&lt;br /&gt;
&lt;br /&gt;
--ssh-secure effectue un audit préalable, prépare un fichier SSH dédié, vérifie la syntaxe et les valeurs effectives, puis recharge SSH. Il désactive l’authentification SSH par mot de passe et conserve root par clé. Les connexions root et ajlsm par clé sont revérifiées par le code reçu.&lt;br /&gt;
&lt;br /&gt;
Le mot de passe local ajlsm reste utile pour sudo. --password-ajlsm utilise un terminal interactif et lance passwd dans la VM, avec sa double saisie masquée. Le secret n’est pas inscrit dans le YAML ni dans la ligne de commande. La procédure historique prévoit un report manuel dans le registre ODS d’administration ; appliquer les règles internes de gestion des secrets. Ne pas joindre ce registre à une documentation publique.&lt;br /&gt;
&lt;br /&gt;
=== 10.4. Certificat TLS interne et Apache ===&lt;br /&gt;
&lt;br /&gt;
--tls-apply lit le certificat /etc/ssl/ajlsm/server.crt. Si le CN et le SAN correspondent déjà au hostname attendu, la phase termine sans réinitialisation. Sinon, après confirmation, elle appelle /usr/local/sbin/ajlsm-init-tls.sh &#039;&#039;&#039;dans la VM&#039;&#039;&#039;. Ce dernier script doit être présent dans le modèle ; son contenu n’était pas inclus dans l’archive des scripts de déploiement reçue.&lt;br /&gt;
&lt;br /&gt;
Après une initialisation réussie, le module contrôle le certificat, apache2ctl configtest et systemctl is-active apache2. Ce contrôle technique d’Apache ne constitue pas une recette des VirtualHosts et des applications du projet.&lt;br /&gt;
&lt;br /&gt;
La documentation historique désigne /home/ajlsm/README, hérité de TEMPLATE3, comme README applicatif Pleade/Drupal. Le conserver séparément du README-ajlsm-deploy de l’outil de déploiement ; ne pas remplacer l’un par l’autre.&lt;br /&gt;
&lt;br /&gt;
=== 10.5. Attente réseau au premier démarrage ===&lt;br /&gt;
&lt;br /&gt;
La recette du 15 octobre signalait environ 60 secondes d’attente dans systemd-networkd-wait-online lorsque les interfaces étaient isolées. Ce constat historique n’a pas empêché l’agent QEMU ni ajlsm-clone-init de répondre. Une optimisation éventuelle du modèle reste distincte du déploiement ; ne pas désactiver le service sans vérifier ses dépendances.&lt;br /&gt;
&lt;br /&gt;
== 11. Maintenance, sauvegardes et manuel ==&lt;br /&gt;
&lt;br /&gt;
=== 11.1. Identifier les fichiers réellement exécutés ===&lt;br /&gt;
&lt;br /&gt;
La recette du 16 octobre utilise le dossier /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/. Elle ne démontre pas une mise à jour globale de /usr/local/sbin/. Toujours distinguer le lot validé et les programmes installés.&lt;br /&gt;
&lt;br /&gt;
Dans le dossier de recette :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy --help&lt;br /&gt;
./ajlsm-deploy-cycle --help&lt;br /&gt;
./ajlsm-deploy-yaml --help&lt;br /&gt;
python3 -m py_compile ajlsm-deploy ajlsm-deploy-check ajlsm-deploy-resources ajlsm-deploy-cycle ajlsm-deploy-yaml ajlsm_deploy_common.py ajlsm_deploy_rootgrow.py ajlsm_deploy_postconfig.py&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Une compilation vérifie la syntaxe, pas le bon déroulement d’une phase ni les prérequis serveur.&lt;br /&gt;
&lt;br /&gt;
=== 11.2. Sauvegarder et restaurer un lot cohérent ===&lt;br /&gt;
&lt;br /&gt;
Conserver ensemble programmes, modules et configuration de référence. Sauvegarder le lot complet avant une installation ou une correction. Exemple sur Saturne3 :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
tar -czf &amp;quot;/root/ajlsm-deploy/archives/lot-recette-$(date +%Y%m%d-%H%M%S).tar.gz&amp;quot; \&lt;br /&gt;
  -C /root/ajlsm-deploy/recettes/20261016 ajlsm-deploy-cycle&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Une restauration doit porter sur un ensemble compatible. Ne pas réinstaller uniquement ajlsm-deploy.bak-20261015 : ce fichier peut précéder les modules et phases nécessaires. L’ancienne sauvegarde et les répertoires de revue sont des références historiques à inventorier avant nettoyage.&lt;br /&gt;
&lt;br /&gt;
Ne pas supprimer INSTRUCTIONS-TEST.txt ou d’autres fichiers de /root/ajlsm-deploy-review/ sur la seule base de l’ancienne page. Leur archivage et le nettoyage ne font pas partie de cette mise à jour documentaire.&lt;br /&gt;
&lt;br /&gt;
=== 11.3. Page man ===&lt;br /&gt;
&lt;br /&gt;
La page du 15 octobre indique un manuel installé en /usr/local/man/man8/ajlsm-deploy.8 et une sauvegarde hors man8 dans /root/ajlsm-deploy-review/sauvegardes-man/. Ce sont des informations historiques, dont l’état actuel n’a pas été vérifié pendant la recette du 16 octobre.&lt;br /&gt;
&lt;br /&gt;
Pour identifier la page disponible sur Saturne3 :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man -w ajlsm-deploy&lt;br /&gt;
man 8 ajlsm-deploy&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Une page absente ne signifie pas que le script est absent : --help est l’aide intégrée de l’exécutable. Le manuel installé doit être réconcilié avec le cycle et l’assistant avant d’être considéré comme référence de cette version. En attendant, le présent guide et l’aide des fichiers du lot de recette décrivent le fonctionnement courant.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
AJLSM-DEPLOY(8)                                     Administration système                                     AJLSM-DEPLOY(8)&lt;br /&gt;
&lt;br /&gt;
NOM&lt;br /&gt;
       ajlsm-deploy - déployer une VM Proxmox par phases contrôlées&lt;br /&gt;
&lt;br /&gt;
SYNOPSIS&lt;br /&gt;
       ajlsm-deploy projet.yaml PHASE [--agent-timeout secondes]&lt;br /&gt;
       ajlsm-deploy-check projet.yaml [--phase proxmox] [--yaml-only]&lt;br /&gt;
       ajlsm-deploy-resources projet.yaml (--dry-run | --apply)&lt;br /&gt;
&lt;br /&gt;
DESCRIPTION&lt;br /&gt;
       Programme  à  exécuter  sur  le  nœud Proxmox cible, avec les droits administrateur. Chaque invocation traite une seule&lt;br /&gt;
       phase.  Le YAML est validé avant les commandes externes.&lt;br /&gt;
&lt;br /&gt;
       Après succès, les suggestions affichent les commandes de simulation et d&#039;exécution de la prochaine étape, ou de l&#039;étape&lt;br /&gt;
       simulée.  Les étapes sans simulation dédiée le signalent explicitement.  Ces suggestions ne sont jamais  exécutées  au‐&lt;br /&gt;
       tomatiquement.  Elles décrivent l&#039;ordre théorique, sans mémoriser l&#039;état du cycle.&lt;br /&gt;
&lt;br /&gt;
       Pour  enchaîner les onze étapes sans en oublier, utiliser ajlsm-deploy-cycle(8).  Ce lanceur conserve les confirmations&lt;br /&gt;
       et les saisies interactives.&lt;br /&gt;
&lt;br /&gt;
ORDRE DES PHASES&lt;br /&gt;
       1. --clone&lt;br /&gt;
              Créer le clone complet, désactiver onboot, isoler les interfaces, vérifier l&#039;arrêt et les  adresses  MAC.  Aucun&lt;br /&gt;
              démarrage.  Simulation : --dry-run, qui comprend les précontrôles.&lt;br /&gt;
&lt;br /&gt;
       2. --configure-resources&lt;br /&gt;
              Configurer  et vérifier CPU, mémoire, balloon et disque scsi0.  Exige une VM arrêtée, onboot désactivé et inter‐&lt;br /&gt;
              faces isolées.  La réduction du disque est interdite.  Simulation : --resources-dry-run.&lt;br /&gt;
&lt;br /&gt;
       3. --first-boot-apply&lt;br /&gt;
              Démarrer le clone isolé, attendre l&#039;agent QEMU et ajlsm-clone-init, puis vérifier les identités  attendues.   Si&lt;br /&gt;
              la VM tourne déjà, reprendre les contrôles sans redémarrage.  Simulation : --first-boot-dry-run.&lt;br /&gt;
&lt;br /&gt;
       4. --root-grow-apply&lt;br /&gt;
              Après  le  premier démarrage et avant la personnalisation système, étendre la partition, le PV LVM, le LV racine&lt;br /&gt;
              et ext4.  Cette étape dépend de etendre_volume_racine dans le YAML.  Simulation : --root-grow-dry-run.&lt;br /&gt;
&lt;br /&gt;
       5. --system-apply&lt;br /&gt;
              Personnaliser hostname, hosts et machine-id, redémarrer isolé et vérifier l&#039;identité active. Respecter le  jour‐&lt;br /&gt;
              nal de transaction.  Simulation : --system-dry-run.&lt;br /&gt;
&lt;br /&gt;
       6. --network-apply&lt;br /&gt;
              Sauvegarder  et  écrire Netplan dans l&#039;invité, puis exécuter netplan generate. Les liens Proxmox restent isolés.&lt;br /&gt;
              Simulation : --network-dry-run.&lt;br /&gt;
&lt;br /&gt;
       7. --network-enable&lt;br /&gt;
              Contrôler identité, configuration et conflits ARP, activer les liens, vérifier adresses, loopback, route, DNS et&lt;br /&gt;
              passerelle, puis appliquer demarrage_auto.  Un mécanisme de repli tente de rétablir l&#039;isolation en cas  d&#039;échec.&lt;br /&gt;
              Simulation : --network-enable-dry-run.&lt;br /&gt;
&lt;br /&gt;
       8. --ssh-audit&lt;br /&gt;
              Comparer  la  clé  ED25519 lue via QEMU à celle exposée sur le réseau, actualiser known_hosts après concordance,&lt;br /&gt;
              puis vérifier les accès, clés autorisées, sudo et état du compte ajlsm.  Aucune simulation dédiée.&lt;br /&gt;
&lt;br /&gt;
       9. --ssh-secure&lt;br /&gt;
              Après audit et confirmation, désactiver l&#039;authentification SSH par mot de passe, conserver root par  clé,  véri‐&lt;br /&gt;
              fier  la  configuration,  recharger  SSH  et  contrôler les connexions root et ajlsm par clé.  Aucune simulation&lt;br /&gt;
              dédiée.&lt;br /&gt;
&lt;br /&gt;
       10. --password-ajlsm&lt;br /&gt;
              Ouvrir passwd pour ajlsm dans la VM avec double saisie native masquée.  Un terminal interactif est  obligatoire.&lt;br /&gt;
              Le mot de passe n&#039;est pas placé dans le YAML ni la ligne de commande.  Aucune simulation dédiée.&lt;br /&gt;
&lt;br /&gt;
       11. --tls-apply&lt;br /&gt;
              Vérifier  le  certificat TLS interne. Si CN et SAN correspondent déjà au hostname, ne pas réinitialiser.  Sinon,&lt;br /&gt;
              après confirmation, appeler ajlsm-init-tls.sh dans la VM, puis vérifier certificat, syntaxe  Apache  et  service&lt;br /&gt;
              actif.  Aucune simulation dédiée.&lt;br /&gt;
&lt;br /&gt;
OPTIONS COMMUNES&lt;br /&gt;
       --agent-timeout secondes&lt;br /&gt;
              Entier  strictement  positif,  défaut 300.  Délai transmis aux attentes utilisant l&#039;agent QEMU.  Il ne constitue&lt;br /&gt;
              pas un délai maximal global.  La phase d&#039;extension racine autorise au moins 600 secondes pour son exécution  in‐&lt;br /&gt;
              vitée après les précontrôles.&lt;br /&gt;
&lt;br /&gt;
       -h, --help&lt;br /&gt;
              Afficher l&#039;aide intégrée sans accéder à Proxmox.&lt;br /&gt;
&lt;br /&gt;
       Choisir  exactement une phase. Les noms des options du programme principal doivent être écrits en entier ; les abrévia‐&lt;br /&gt;
       tions telles que --network-dry sont refusées.&lt;br /&gt;
&lt;br /&gt;
CONFIRMATIONS&lt;br /&gt;
       Seul OUI, sans distinction de casse et après suppression des espaces périphériques, autorise une opération à  la  ques‐&lt;br /&gt;
       tion correspondante.  NON, vide, autre réponse, EOF ou interruption pendant la question annulent. Il n&#039;existe pas d&#039;op‐&lt;br /&gt;
       tion de confirmation automatique.  Une étape déjà conforme peut terminer sans modification ni nouvelle confirmation.&lt;br /&gt;
&lt;br /&gt;
EXTENSION RACINE&lt;br /&gt;
       Le  disque  Proxmox  agrandi  par  la phase ressources ne suffit pas à agrandir le système de fichiers de l&#039;invité.  La&lt;br /&gt;
       phase racine réalise growpart, pvresize et lvextend avec redimensionnement du système de fichiers.&lt;br /&gt;
&lt;br /&gt;
       Topologie prise en charge : racine ext4, PV /dev/sda3, partition terminale parmi trois partitions de /dev/sda, un  seul&lt;br /&gt;
       PV  et  un seul LV. La taille du disque doit correspondre au YAML. Les outils doivent déjà être présents ; aucun paquet&lt;br /&gt;
       n&#039;est installé par cette phase.&lt;br /&gt;
&lt;br /&gt;
       Si la partition est déjà agrandie, le code saute growpart et poursuit le traitement LVM. Si etendre_volume_racine  vaut&lt;br /&gt;
       false, la phase annonce sa désactivation. Vérifier ensuite lsblk et df -hT /.&lt;br /&gt;
&lt;br /&gt;
SSH ET TLS&lt;br /&gt;
       L&#039;audit  SSH  n&#039;est  pas  intégralement sans écriture : il peut sauvegarder et actualiser /root/.ssh/known_hosts sur le&lt;br /&gt;
       nœud Proxmox après comparaison indépendante des clés QEMU/réseau.  Une divergence provoque un refus ; ne pas  supprimer&lt;br /&gt;
       aveuglément known_hosts pour contourner ce contrôle.&lt;br /&gt;
&lt;br /&gt;
       La  structure  binaire ED25519 est contrôlée avant comparaison.  Une clé absente ou malformée provoque également un re‐&lt;br /&gt;
       fus.  Après concordance, les anciennes entrées de l&#039;IP cible, y compris hachées, sont retirées de la copie de  travail.&lt;br /&gt;
       Les autres hôtes sont conservés et le remplacement est atomique.&lt;br /&gt;
&lt;br /&gt;
       Le  mot de passe local ajlsm reste utile pour sudo même lorsque l&#039;authentification SSH par mot de passe est désactivée.&lt;br /&gt;
       Le conserver selon la procédure interne de gestion des secrets.  La procédure AJLSM prévoit un report  manuel  dans  le&lt;br /&gt;
       registre ODS d&#039;administration ; ne pas inclure ce registre dans le YAML.&lt;br /&gt;
&lt;br /&gt;
       Le  certificat  interne  et le contrôle technique d&#039;Apache ne valident pas les VirtualHosts ni les applications. ajlsm-&lt;br /&gt;
       init-tls.sh doit être présent dans l&#039;invité ; son contenu n&#039;est pas fourni par le lot de scripts du nœud Proxmox.&lt;br /&gt;
&lt;br /&gt;
FORMAT YAML&lt;br /&gt;
       Sections obligatoires : projet, proxmox, systeme et reseau.  Les clés inconnues, répétées ou manquantes sont  refusées.&lt;br /&gt;
       Seul  proxmox.vmid  peut rester null pour une attribution automatique.  Ce VMID n&#039;est pas réservé avant clonage et peut&lt;br /&gt;
       changer.&lt;br /&gt;
&lt;br /&gt;
       projet.environnement et tags acceptent interne, client ou prod.  Les tags forment une liste sans doublon ; []  est  ad‐&lt;br /&gt;
       mis.   Les  ressources  exigent des entiers positifs ; la mémoire minimale ne dépasse pas la maximale. Utiliser true ou&lt;br /&gt;
       false pour les booléens.&lt;br /&gt;
&lt;br /&gt;
       Les chaînes numériques et les booléens ne sont pas convertis en entiers par le validateur. Le VMID explicite doit  être&lt;br /&gt;
       différent du template_vmid. Aucune correspondance automatique n&#039;est imposée entre l&#039;environnement et les tags.&lt;br /&gt;
&lt;br /&gt;
       Hostname DNS en minuscules ; interfaces Proxmox netN et invitées ensN.  Les IPv4 d&#039;interfaces exigent un préfixe CIDR ;&lt;br /&gt;
       la  loopback  exige  /32.  La passerelle est dans le sous-réseau de son interface déclarée.  Les interfaces et adresses&lt;br /&gt;
       sont uniques.  Les DNS forment une liste non vide d&#039;IPv4 sans préfixe.  La passerelle doit différer  des  adresses  des&lt;br /&gt;
       interfaces.   Les adresses réseau et broadcast sont refusées pour les sous-réseaux de préfixe inférieur à 31.  Serveur,&lt;br /&gt;
       stockage et bridge restent des valeurs d&#039;infrastructure à renseigner ; aucune liste  fermée  n&#039;est  inventée  pour  ces&lt;br /&gt;
       champs.&lt;br /&gt;
&lt;br /&gt;
       Préparer  le  fichier  avec  ajlsm-deploy-yaml(8).   projet-vierge.yaml  est volontairement incomplet.  mercure3-refer‐&lt;br /&gt;
       ence.yaml conserve les paramètres de reconstruction, pas les données, secrets ou anciennes identités de la VM.&lt;br /&gt;
&lt;br /&gt;
AUXILIAIRES&lt;br /&gt;
       ajlsm-deploy-check&lt;br /&gt;
              Valider le YAML, puis contrôler le modèle, ses  ressources,  le  stockage  et  les  bridges  pour  une  nouvelle&lt;br /&gt;
              création.   --phase  accepte uniquement proxmox.  --yaml-only effectue seulement la validation locale, sans com‐&lt;br /&gt;
              mande Proxmox. Une VM de projet déjà existante peut faire échouer les contrôles de nouvelle création.&lt;br /&gt;
&lt;br /&gt;
       ajlsm-deploy-resources&lt;br /&gt;
              Configurer les ressources avec --apply, ou simuler avec --dry-run. Ces modes  sont  exclusifs  et  obligatoires.&lt;br /&gt;
              Les  protections sont revérifiées avant chaque écriture.  Le programme refuse notamment une cible modèle ou con‐&lt;br /&gt;
              fondue avec la source, et un VMID explicite incohérent.&lt;br /&gt;
&lt;br /&gt;
PRÉREQUIS&lt;br /&gt;
       Python 3.9 ou supérieur, PyYAML 6, outils Proxmox et outils réseau.  Conserver le principal, ses  deux  auxiliaires  et&lt;br /&gt;
       les  modules  common, rootgrow et postconfig dans le même répertoire.  Les auxiliaires doivent être exécutables et leur&lt;br /&gt;
       Python doit disposer de PyYAML.&lt;br /&gt;
&lt;br /&gt;
       Le modèle arrêté doit disposer de l&#039;agent QEMU, ajlsm-clone-init, Python, systemd, Netplan, outils LVM et outils  d&#039;ex‐&lt;br /&gt;
       tension.  Les phases postréseau nécessitent les accès SSH par clé prévus et le script TLS invité.&lt;br /&gt;
&lt;br /&gt;
FICHIERS&lt;br /&gt;
       /etc/ajlsm/deploy/projets/&lt;br /&gt;
              Configurations des projets.&lt;br /&gt;
&lt;br /&gt;
       /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/&lt;br /&gt;
              Lot de recette validé le 16 octobre 2026.  Utiliser les chemins ./ pour ne pas appeler une ancienne version.&lt;br /&gt;
&lt;br /&gt;
       /usr/local/sbin/&lt;br /&gt;
              Programmes installés antérieurement ; leur mise à jour n&#039;est pas prouvée par le succès du lot de recette.&lt;br /&gt;
&lt;br /&gt;
       /var/lib/ajlsm/system-personalisation/&lt;br /&gt;
              Journal et sauvegardes d&#039;identité dans l&#039;invité.  Ne pas effacer pour forcer une reprise.&lt;br /&gt;
&lt;br /&gt;
LIMITES&lt;br /&gt;
       Les  simulations  ne  sont pas toutes hors ligne : la simulation d&#039;activation réseau émet des sondes ARP.  L&#039;absence de&lt;br /&gt;
       réponse ne garantit pas la disponibilité d&#039;une IP.  Le repli réseau en situation réelle reste à recetter.&lt;br /&gt;
&lt;br /&gt;
       Les validations locales ne certifient pas DNS, OPNsense ou Ansible.   NFS,  VirtualHosts  Apache2,  Pleade,  Drupal  et&lt;br /&gt;
       Matomo restent hors du cycle applicatif actuellement implémenté.&lt;br /&gt;
&lt;br /&gt;
       Le  README  applicatif /home/ajlsm/README hérité du modèle est distinct du README de déploiement. Ne pas remplacer l&#039;un&lt;br /&gt;
       par l&#039;autre.&lt;br /&gt;
&lt;br /&gt;
CODES DE SORTIE&lt;br /&gt;
       0 : succès. 1 : annulation. 2 : erreur.  L&#039;aide quitte avec 0 ; une erreur d&#039;arguments quitte avec 2.&lt;br /&gt;
&lt;br /&gt;
EXEMPLES&lt;br /&gt;
       Depuis le dossier de recette, sur Saturne3 :&lt;br /&gt;
       ./ajlsm-deploy-check projet.yaml --yaml-only&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --dry-run&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --clone&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --resources-dry-run&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --configure-resources&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --first-boot-dry-run&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --first-boot-apply&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --root-grow-dry-run&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --root-grow-apply&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --system-dry-run&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --system-apply&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --network-dry-run&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --network-apply&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --network-enable-dry-run&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --network-enable&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --ssh-audit&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --ssh-secure&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --password-ajlsm&lt;br /&gt;
       ./ajlsm-deploy projet.yaml --tls-apply&lt;br /&gt;
       Les simulations sont facultatives. Le mode manuel exige le contrôle de l&#039;ordre des phases. Pour l&#039;enchaînement guidé :&lt;br /&gt;
       ./ajlsm-deploy-cycle projet.yaml --plan&lt;br /&gt;
       ./ajlsm-deploy-cycle projet.yaml&lt;br /&gt;
       Ne pas relancer un cycle de création sur MERCURE3 déjà déployée.&lt;br /&gt;
&lt;br /&gt;
ÉTAT DE LA RECETTE&lt;br /&gt;
       Le manuel installé reçu portait la date du 15 octobre 2026.  Il décrivait déjà les phases racine, SSH et TLS, mais  pas&lt;br /&gt;
       le nouveau lanceur ni l&#039;assistant YAML.&lt;br /&gt;
&lt;br /&gt;
       Le  16 octobre, les sorties transmises ont confirmé la fin du cycle complet sur MERCURE3. Les vérifications finales ont&lt;br /&gt;
       confirmé SSH, sudo, mercure3.ajlsm.com et une racine ext4 de 97 Gio.  Les scénarios négatifs de clés SSH  étaient  rap‐&lt;br /&gt;
       portés  comme  tests  isolés  du  15 octobre ; ils n&#039;ont pas été rejoués lors de la présente révision documentaire.  Le&lt;br /&gt;
       repli réseau réel reste distinct de cette recette nominale.&lt;br /&gt;
&lt;br /&gt;
VOIR AUSSI&lt;br /&gt;
       ajlsm-deploy-cycle(8), ajlsm-deploy-yaml(8), qm(1), lvm(8).&lt;br /&gt;
&lt;br /&gt;
AJLSM                                                  October 16, 2026                                        AJLSM-DEPLOY(8)&lt;br /&gt;
~&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 12. État des validations et limites ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Date / source !! Vérification !! Portée&lt;br /&gt;
|-&lt;br /&gt;
| 15/10/2026, page historique || Déploiements initiaux jusqu’à l’activation réseau || Résultats historiques conservés ; ne décrivent pas à eux seuls le cycle actuel&lt;br /&gt;
|-&lt;br /&gt;
| 15/10/2026, page historique || Comparaison ED25519, clés divergentes ou malformées, préservation de known_hosts || Tests isolés rapportés dans la documentation reçue, non rejoués lors de cette consolidation&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, tests locaux du lot cycle || Ordre des 11 étapes, arrêt sur refus/erreur, reprise et suggestions || 8 tests réussis, incluant des sous-cas ; sous-processus des phases simulés&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, sorties Saturne3 transmises || Cycle technique complet sur un nouveau clone MERCURE3 || Terminé sans erreur signalée, extension racine incluse&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, sorties invitées transmises || SSH ajlsm, sudo, hostname et racine ext4 || Confirmés ; mercure3.ajlsm.com et 97 Gio pour /&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, tests locaux assistant || Création, correction, copie, validation et annulation || 14 tests réussis, saisies simulées&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, sortie Saturne3 transmise || Assistant --check sur mercure3.yaml || Valeurs YAML valides ; aucune écriture ni validation externe&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, vérification locale des modèles || Modèle vierge complété par l’assistant || Paramètres identiques à la référence MERCURE3 ; original intact&lt;br /&gt;
|-&lt;br /&gt;
| À réaliser || Essai réel du mécanisme de repli après échec d’activation réseau || Non confirmé ; le succès du parcours nominal ne valide pas ce scénario&lt;br /&gt;
|-&lt;br /&gt;
| À réaliser || Vérifications automatiques DNS, OPNsense, Ansible et recette applicative || Hors périmètre actuel&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le message de fin du cycle signifie que ses phases ont retourné un succès. Il ne vaut pas validation des applications ni détection de toutes les défaillances possibles. Conserver les vérifications finales et les limites propres aux phases.&lt;br /&gt;
&lt;br /&gt;
== 13. Réconciliation avec la page du 15 octobre ==&lt;br /&gt;
&lt;br /&gt;
L’original reçu est conservé intégralement dans historique/guide-20261015.mediawiki. Il sert de trace, pas de seconde procédure opérationnelle concurrente.&lt;br /&gt;
&lt;br /&gt;
Le présent document remplace les indications opérationnelles anciennes :&lt;br /&gt;
* confirmations CLONER/APPLIQUER/DEMARRER remplacées par OUI/NON ;&lt;br /&gt;
* parcours manuel seul remplacé par le choix entre mode manuel et cycle interactif ;&lt;br /&gt;
* liste des étapes incluant l’extension racine, SSH, mot de passe et TLS ;&lt;br /&gt;
* extension racine et cycle complet désormais validés sur la recette du 16 octobre ;&lt;br /&gt;
* suggestions manuelles affichant les deux commandes disponibles, sans oublier l’extension racine ;&lt;br /&gt;
* création et relecture du YAML par l’assistant, sans écraser l’original ;&lt;br /&gt;
* ajout du modèle vierge et de la référence MERCURE3 renseignée ;&lt;br /&gt;
* séparation explicite des scripts installés, du lot de recette, du manuel historique et de la future installation.&lt;br /&gt;
&lt;br /&gt;
Les détails encore utiles de l’ancienne page sur l’isolation, les transactions, ED25519, les sauvegardes, le README applicatif et les limites de validation sont repris ci-dessus. Une nouvelle mise à jour fonctionnelle doit modifier cette procédure directement plutôt que superposer une nouvelle section corrective à une ancienne procédure contradictoire.&lt;br /&gt;
&lt;br /&gt;
== 14. Suites prévues ==&lt;br /&gt;
&lt;br /&gt;
Prévoir les paramètres NFS, sites Apache2, Pleade, Drupal et Matomo dans le même YAML lorsque leurs exigences seront définies. Modifier ensemble le schéma, l’assistant, les modèles, les précontrôles, les phases et leur documentation. Documenter les références aux secrets plutôt que leurs valeurs.&lt;br /&gt;
&lt;br /&gt;
L’intégration des contrôles DNS, OPNsense et Ansible précédera une déclaration automatisée de disponibilité du projet. Le modèle actuel ne contient pas encore ces nouvelles sections.&lt;br /&gt;
&lt;br /&gt;
[[Catégorie:Infrastructure]]&lt;br /&gt;
[[Catégorie:Proxmox]]&lt;br /&gt;
[[Catégorie:Déploiement]]&lt;br /&gt;
[[Catégorie:AJLSM]]&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=D%C3%A9ploiement_technique_d%E2%80%99une_VM_AJLSM&amp;diff=6496</id>
		<title>Déploiement technique d’une VM AJLSM</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=D%C3%A9ploiement_technique_d%E2%80%99une_VM_AJLSM&amp;diff=6496"/>
		<updated>2026-10-16T16:38:39Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : /* 11.3. Page man */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= AJLSM-DEPLOY — Déploiement automatisé des VM Proxmox =&lt;br /&gt;
&lt;br /&gt;
Document consolidé au 16 octobre 2026. Cette procédure réunit la page du 15 octobre et la recette actuelle. Elle remplace leurs indications opérationnelles divergentes. L’original du 15 octobre reste archivé séparément.&lt;br /&gt;
&lt;br /&gt;
Référence technique : scripts reçus de Saturne3, puis lot de recette avec lanceur du cycle et assistant YAML.&lt;br /&gt;
&lt;br /&gt;
== 1. Périmètre et résultat de la recette ==&lt;br /&gt;
&lt;br /&gt;
Le cycle technique a été exécuté sur MERCURE3 sans erreur signalée. Les vérifications finales transmises confirment :&lt;br /&gt;
* connexion SSH avec le compte ajlsm ;&lt;br /&gt;
* élévation sudo avec le mot de passe défini pendant le cycle ;&lt;br /&gt;
* hostname mercure3.ajlsm.com ;&lt;br /&gt;
* volume racine ext4 de 97 Gio, dont 85 Gio disponibles lors du contrôle.&lt;br /&gt;
&lt;br /&gt;
Le cycle couvre le clonage, les ressources, l’initialisation du clone, l’extension de la racine, l’identité système, le réseau, SSH, le mot de passe et le certificat TLS interne.&lt;br /&gt;
&lt;br /&gt;
NFS, les configurations applicatives Apache2, Pleade, Drupal et Matomo ne font pas encore partie de ce cycle. Certains logiciels peuvent déjà être présents dans le modèle : leur présence ne constitue pas une configuration applicative du projet.&lt;br /&gt;
&lt;br /&gt;
== 2. Où exécuter les commandes ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Machine !! Rôle !! Exemple d’invite&lt;br /&gt;
|-&lt;br /&gt;
| Mac de l’administrateur || Transfert des archives par scp || Invite locale du Mac&lt;br /&gt;
|-&lt;br /&gt;
| Saturne3 || Préparation YAML, scripts Proxmox et cycle || root@Saturne3&lt;br /&gt;
|-&lt;br /&gt;
| MERCURE3 || Vérifications dans la VM || ajlsm@mercure3 ou root@mercure3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les scripts de déploiement sont exécutés sur Saturne3, pas dans MERCURE3.&lt;br /&gt;
Après « ssh ajlsm@10.0.0.43 », attendre l’invite de la VM avant de saisir les commandes suivantes.&lt;br /&gt;
Pour revenir de root@mercure3 à Saturne3 : un exit quitte sudo, puis un second exit ferme SSH.&lt;br /&gt;
&lt;br /&gt;
== 3. Organisation des fichiers ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/root/ajlsm-deploy/&lt;br /&gt;
  archives/                         Archives reçues, conservées comme références&lt;br /&gt;
  recettes/20261016/&lt;br /&gt;
    ajlsm-deploy-cycle/             Lot technique validé et assistant ajouté&lt;br /&gt;
    ajlsm-deploy-assistant/         Distribution de l’assistant et tests&lt;br /&gt;
    ajlsm-deploy-documentation/     Présent guide et modèles YAML&lt;br /&gt;
&lt;br /&gt;
/etc/ajlsm/deploy/projets/mercure3.yaml   Configuration actuellement utilisée&lt;br /&gt;
/usr/local/sbin/                        Scripts installés antérieurement&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le lot de recette contient ajlsm-deploy, ajlsm-deploy-check, ajlsm-deploy-resources, ajlsm-deploy-cycle et les modules ajlsm_deploy_common.py, ajlsm_deploy_rootgrow.py et ajlsm_deploy_postconfig.py. L’assistant ajlsm-deploy-yaml a été ajouté à ce même dossier.&lt;br /&gt;
&lt;br /&gt;
Conserver exécutables et modules ensemble. Utiliser les chemins ./ depuis le dossier de recette pour ne pas appeler une ancienne version de /usr/local/sbin.&lt;br /&gt;
Les anciennes archives « ajlsm-deploy-revise » et « correction-suggestions » ne sont pas la référence courante : elles précèdent les phases supplémentaires reçues dans l’archive serveur.&lt;br /&gt;
&lt;br /&gt;
Prérequis : Python 3.9 ou supérieur, PyYAML 6, outils Proxmox sur le nœud cible et prérequis du modèle AJLSM. Les phases invitées utilisent notamment l’agent QEMU, ajlsm-clone-init, Python, systemd et Netplan. L’extension actuelle cible ext4/LVM sur /dev/sda3, avec un seul PV et un seul LV.&lt;br /&gt;
&lt;br /&gt;
== 4. Les deux fichiers de préconfiguration ==&lt;br /&gt;
&lt;br /&gt;
=== 4.1. projet-vierge.yaml ===&lt;br /&gt;
&lt;br /&gt;
Ce modèle reprend toute la structure actuelle sans valeur opérationnelle préremplie. Chaque champ doit être renseigné. Seul proxmox.vmid peut rester null : il signifie alors attribution automatique.&lt;br /&gt;
&lt;br /&gt;
Le modèle comporte deux interfaces dont les valeurs sont null. Adapter le nombre d’interfaces avant la saisie si nécessaire. Pour déterminer ce nombre par les questions de l’assistant, utiliser plutôt le mode --new.&lt;br /&gt;
&lt;br /&gt;
Un modèle vierge est volontairement refusé par --check. Il ne doit jamais être passé directement au lanceur du cycle.&lt;br /&gt;
&lt;br /&gt;
=== 4.2. mercure3-reference.yaml ===&lt;br /&gt;
&lt;br /&gt;
Ce fichier conserve les valeurs du projet validé : modèle 506 sur Saturne3, nom MERCURE3, 8 vCPU, 24576 Mio de RAM maximale, 16384 Mio minimale, disque 100 Gio, extension racine activée et paramètres réseau du projet.&lt;br /&gt;
&lt;br /&gt;
Il permet de reconstruire une nouvelle VM avec la même configuration technique si le modèle, le stockage, les bridges et les préparatifs externes sont toujours disponibles. Il ne sauvegarde ni les données de l’ancienne VM, ni ses UUID, machine-id, clés hôte SSH ou mots de passe. Ces identités sont traitées par le cycle et ne sont pas à recopier.&lt;br /&gt;
&lt;br /&gt;
Avec vmid: null, le VMID de remplacement peut différer de celui de l’ancienne VM. Le VMID 505 observé pendant la recette n’est pas une réservation permanente.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ne pas lancer cette référence tant que MERCURE3 existe encore.&#039;&#039;&#039; Le clonage refuse un nom déjà présent. Pour tester une deuxième VM en parallèle, définir un autre nom, hostname, des IP distinctes et préparer DNS/OPNsense/Ansible en conséquence.&lt;br /&gt;
&lt;br /&gt;
=== 4.3. Valeurs acceptées ===&lt;br /&gt;
&lt;br /&gt;
* projet.environnement et tags : interne, client, prod. Les tags sont une liste sans doublons ; [] est admis.&lt;br /&gt;
* CPU, mémoire et taille du disque : entiers strictement positifs ; mémoire minimale inférieure ou égale à la maximale.&lt;br /&gt;
* Booléens : utiliser true ou false sans guillemets.&lt;br /&gt;
* Interfaces Proxmox : net suivi de chiffres ; interfaces invitées : ens suivi de chiffres.&lt;br /&gt;
* Adresses d’interfaces : IPv4/CIDR. Loopback : IPv4/32. Passerelle et DNS : IPv4 sans préfixe.&lt;br /&gt;
* Passerelle : interface déclarée et adresse appartenant à son sous-réseau, distincte des adresses de la VM.&lt;br /&gt;
* Hostname : nom DNS en minuscules.&lt;br /&gt;
* Serveur, bridge et stockage : valeurs adaptées à l’infrastructure ; aucune liste fermée inventée.&lt;br /&gt;
&lt;br /&gt;
Les clés inconnues ou répétées sont refusées. Ne pas ajouter de sections applicatives avant l’évolution coordonnée du schéma et des scripts. Ne pas utiliser [à renseigner] : les crochets créent une liste YAML.&lt;br /&gt;
&lt;br /&gt;
== 5. Préparer et valider le YAML ==&lt;br /&gt;
&lt;br /&gt;
Sur Saturne3, se placer dans le lot de recette :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5.1. Vérifier un fichier existant sans le modifier ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml /etc/ajlsm/deploy/projets/mercure3.yaml --check&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le message de succès signifie que les valeurs et leur cohérence locale sont conformes. Il ne certifie pas la préparation des services externes.&lt;br /&gt;
&lt;br /&gt;
Voici un exemple : &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;projet:&lt;br /&gt;
  code: mercure3&lt;br /&gt;
  nom: MERCURE3&lt;br /&gt;
  environnement: interne&lt;br /&gt;
&lt;br /&gt;
proxmox:&lt;br /&gt;
  serveur: Saturne3&lt;br /&gt;
  template_vmid: 506&lt;br /&gt;
  vmid: null&lt;br /&gt;
  nom_vm: MERCURE3&lt;br /&gt;
&lt;br /&gt;
  cpu:&lt;br /&gt;
    sockets: 1&lt;br /&gt;
    cores: 8&lt;br /&gt;
&lt;br /&gt;
  memoire:&lt;br /&gt;
    maximale_mib: 24576&lt;br /&gt;
    minimale_mib: 16384&lt;br /&gt;
&lt;br /&gt;
  disque_systeme:&lt;br /&gt;
    stockage: local-zfs&lt;br /&gt;
    taille_gib: 100&lt;br /&gt;
    etendre_volume_racine: true&lt;br /&gt;
&lt;br /&gt;
  demarrage_auto: true&lt;br /&gt;
&lt;br /&gt;
  tags:&lt;br /&gt;
    - interne&lt;br /&gt;
&lt;br /&gt;
systeme:&lt;br /&gt;
  hostname: mercure3.ajlsm.com&lt;br /&gt;
&lt;br /&gt;
reseau:&lt;br /&gt;
  interfaces:&lt;br /&gt;
    - nom: net0&lt;br /&gt;
      bridge: vmbr2&lt;br /&gt;
      systeme: ens18&lt;br /&gt;
      ipv4: 10.0.0.43/24&lt;br /&gt;
&lt;br /&gt;
    - nom: net1&lt;br /&gt;
      bridge: vmbr1&lt;br /&gt;
      systeme: ens19&lt;br /&gt;
      ipv4: 192.168.123.27/24&lt;br /&gt;
&lt;br /&gt;
  loopback:&lt;br /&gt;
    ipv4: 51.83.117.113/32&lt;br /&gt;
&lt;br /&gt;
  passerelle:&lt;br /&gt;
    ipv4: 10.0.0.4&lt;br /&gt;
    interface: ens18&lt;br /&gt;
&lt;br /&gt;
  dns:&lt;br /&gt;
    - 10.0.0.4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5.2. Compléter le modèle vierge ===&lt;br /&gt;
&lt;br /&gt;
Après extraction du présent lot documentaire :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml \&lt;br /&gt;
  /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-documentation/projet-vierge.yaml \&lt;br /&gt;
  --output /root/ajlsm-deploy/recettes/20261016/nouveau-projet.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Toutes les valeurs obligatoires seront demandées. Pour saisir de nouveau le projet MERCURE3, consulter mercure3-reference.yaml comme fiche de paramètres, sans lancer de déploiement.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;# Préconfiguration AJLSM vierge : aucune valeur d’infrastructure préremplie.&lt;br /&gt;
# Compléter avec ajlsm-deploy-yaml ; ne pas déployer ce modèle tel quel.&lt;br /&gt;
# null = champ à renseigner, SAUF proxmox.vmid où null = attribution automatique.&lt;br /&gt;
# Les crochets [à renseigner] sont interdits : ils représenteraient une liste YAML.&lt;br /&gt;
# Deux interfaces sont proposées : adapter leur nombre avant la saisie.&lt;br /&gt;
projet:&lt;br /&gt;
  code: null  # Obligatoire : minuscules/chiffres, tiret et souligné ; ex. mercure3.&lt;br /&gt;
  nom: null  # Obligatoire : nom lisible du projet.&lt;br /&gt;
  environnement: null  # Liste fermée : interne, client, prod.&lt;br /&gt;
&lt;br /&gt;
proxmox:&lt;br /&gt;
  serveur: null  # Obligatoire : nom du nœud Proxmox, ex. Saturne3.&lt;br /&gt;
  template_vmid: null  # Obligatoire : entier positif, VM modèle existante et arrêtée.&lt;br /&gt;
  vmid: null  # Automatique ; sinon entier positif différent de template_vmid.&lt;br /&gt;
  nom_vm: null  # Obligatoire : nom de VM, lettres/chiffres/point/tiret.&lt;br /&gt;
  cpu:&lt;br /&gt;
    sockets: null  # Obligatoire : entier positif.&lt;br /&gt;
    cores: null  # Obligatoire : entier positif ; vCPU = sockets × cores.&lt;br /&gt;
  memoire:&lt;br /&gt;
    maximale_mib: null  # Obligatoire : entier positif, en Mio.&lt;br /&gt;
    minimale_mib: null  # Obligatoire : entier positif, inférieur ou égal au maximum.&lt;br /&gt;
  disque_systeme:&lt;br /&gt;
    stockage: null  # Obligatoire : identifiant de stockage Proxmox existant.&lt;br /&gt;
    taille_gib: null  # Obligatoire : entier positif en Gio ; aucune réduction de disque.&lt;br /&gt;
    etendre_volume_racine: null  # Obligatoire : true ou false ; active la phase racine.&lt;br /&gt;
  demarrage_auto: null  # Obligatoire : true ou false ; appliqué à l’activation réseau.&lt;br /&gt;
  tags: null  # Obligatoire : liste ; interne/client/prod uniquement, sans doublons ; [] admis.&lt;br /&gt;
&lt;br /&gt;
systeme:&lt;br /&gt;
  hostname: null  # Obligatoire : nom DNS en minuscules ; vérifier sa déclaration en amont.&lt;br /&gt;
&lt;br /&gt;
reseau:&lt;br /&gt;
  interfaces:&lt;br /&gt;
    - nom: null  # Obligatoire : net suivi de chiffres, conforme à la VM modèle.&lt;br /&gt;
      bridge: null  # Obligatoire : bridge existant, au plus 15 caractères.&lt;br /&gt;
      systeme: null  # Obligatoire : ens suivi de chiffres, conforme au modèle actuel.&lt;br /&gt;
      ipv4: null  # Obligatoire : IPv4/CIDR, ex. 10.0.0.43/24 ; adresse unique.&lt;br /&gt;
    - nom: null&lt;br /&gt;
      bridge: null&lt;br /&gt;
      systeme: null&lt;br /&gt;
      ipv4: null&lt;br /&gt;
  loopback:&lt;br /&gt;
    ipv4: null  # Obligatoire : IPv4 avec préfixe /32, distincte des interfaces.&lt;br /&gt;
  passerelle:&lt;br /&gt;
    ipv4: null  # Obligatoire : IPv4 seule, dans le sous-réseau de son interface.&lt;br /&gt;
    interface: null  # Obligatoire : un des noms systeme déclarés ci-dessus.&lt;br /&gt;
  dns: null  # Obligatoire : liste non vide d’IPv4 sans préfixe, ex. [10.0.0.4].&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5.3. Créer sans modèle ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml /root/ajlsm-deploy/recettes/20261016/nouveau-projet.yaml --new&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette commande est une alternative à la précédente : le chemin doit être inexistant. L’assistant pose les questions, y compris le nombre d’interfaces, sans reprendre implicitement les valeurs de MERCURE3.&lt;br /&gt;
&lt;br /&gt;
=== 5.4. Revoir un projet renseigné ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml /etc/ajlsm/deploy/projets/mercure3.yaml --review \&lt;br /&gt;
  --output /root/ajlsm-deploy/recettes/20261016/mercure3-relecture.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Entrée conserve une valeur existante valide.&lt;br /&gt;
* ANNULER, Ctrl-C ou fin d’entrée abandonnent sans enregistrer.&lt;br /&gt;
* Tags et DNS sont saisis séparés par des virgules ; [] ou aucun signifie tags vides.&lt;br /&gt;
* Saisir auto ou null pour un VMID automatique.&lt;br /&gt;
* Après une incohérence, donner le chemin du champ à corriger ; ? affiche les chemins.&lt;br /&gt;
* Le résumé complet est présenté avant confirmation OUI/NON d’enregistrement.&lt;br /&gt;
&lt;br /&gt;
L’original reste intact, avec ses commentaires. La copie est réécrite en YAML, sans reprise des commentaires. Aucun fichier existant n’est écrasé. Si une destination existe, choisir un nouveau nom avec --output.&lt;br /&gt;
&lt;br /&gt;
=== 5.5. Préparatifs externes ===&lt;br /&gt;
&lt;br /&gt;
Avant une création, vérifier séparément la réservation des IP, les déclarations DNS, les règles/routes/NAT nécessaires dans OPNsense et l’inventaire ou les préparatifs Ansible. Ne pas inscrire de mots de passe dans le YAML ; conserver les secrets dans le dispositif prévu pour leur gestion.&lt;br /&gt;
&lt;br /&gt;
L’assistant actuel ne vérifie pas automatiquement ces services et ne marque pas un projet « prêt à déployer » sur cette seule base. Leur intégration reste à réaliser.&lt;br /&gt;
&lt;br /&gt;
Le contrôle Proxmox autonome examine notamment le modèle, ses ressources, le stockage et les bridges. Il concerne une nouvelle création et peut refuser un projet déjà déployé :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-check /chemin/vers/projet.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 6. Afficher le plan puis lancer le cycle ==&lt;br /&gt;
&lt;br /&gt;
=== 6.1. Plan sans exécution ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /chemin/vers/projet.yaml --plan&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le plan valide le YAML et affiche les commandes, sans exécuter les phases ni vérifier l’infrastructure. Il doit contenir les 11 étapes, toutes dans le dossier de recette.&lt;br /&gt;
&lt;br /&gt;
=== 6.2. Cycle réel pour une nouvelle VM ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /chemin/vers/projet.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le lanceur exécute les phases réelles, sans simulation automatique. Il attend seulement les confirmations, les saisies nécessaires et la fin de chaque commande. Il s’arrête sur refus ou erreur. Il ne répond pas à la place de l’administrateur et ne capture pas les mots de passe.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! N° !! Étape !! Commande réelle !! Simulation facultative&lt;br /&gt;
|-&lt;br /&gt;
| 1 || Clonage || --clone || --dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Ressources || --configure-resources || --resources-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Premier démarrage isolé || --first-boot-apply || --first-boot-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Extension partition/LVM/ext4 || --root-grow-apply || --root-grow-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Identité système || --system-apply || --system-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Préparation Netplan || --network-apply || --network-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Activation réseau || --network-enable || --network-enable-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Audit SSH || --ssh-audit || Aucune option dédiée&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Sécurisation SSH || --ssh-secure || Aucune option dédiée&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Mot de passe ajlsm || --password-ajlsm || Aucune option dédiée&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Certificat TLS interne || --tls-apply || Aucune option dédiée&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
L’extension racine est indispensable quand etendre_volume_racine vaut true. Agrandir le disque Proxmox ne suffit pas : la partition, le PV LVM, le LV et ext4 doivent aussi être étendus. Cette phase doit figurer après le premier démarrage, avant la personnalisation système. Avec false, la phase annonce sa désactivation.&lt;br /&gt;
&lt;br /&gt;
Le démarrage et la personnalisation se font réseau isolé. Netplan est préparé avant activation des liens. La phase d’activation contrôle le réseau et applique demarrage_auto.&lt;br /&gt;
&lt;br /&gt;
Le certificat TLS interne ne constitue pas, à lui seul, une configuration des applications du projet ou un certificat publiquement reconnu.&lt;br /&gt;
&lt;br /&gt;
=== 6.3. Mode manuel ===&lt;br /&gt;
&lt;br /&gt;
Chaque phase peut être lancée séparément avec ./ajlsm-deploy suivi du YAML et de son option. Après succès, le lot courant affiche deux lignes pour l’étape suivante : Simulation et Exécution. Si la simulation n’existe pas, il le signale. Aucune suggestion n’est exécutée automatiquement.&lt;br /&gt;
&lt;br /&gt;
Les simulations peuvent consulter l’invité et émettre des sondes ARP selon la phase : elles ne sont pas toutes des contrôles hors ligne. L’absence de réponse ARP ne remplace pas la réservation des adresses dans l’inventaire réseau.&lt;br /&gt;
&lt;br /&gt;
== 7. Erreur, annulation et reprise ==&lt;br /&gt;
&lt;br /&gt;
Conserver la sortie complète et diagnostiquer la phase fautive avant de reprendre. Une phase peut être partiellement effectuée ; le lanceur n’effectue ni suppression de VM ni restauration globale automatique.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /chemin/vers/projet.yaml --from extension-racine&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--from inclut l’étape indiquée et saute les précédentes à la demande de l’administrateur. Il ne certifie pas leur état. Les contrôles propres aux phases restent actifs. Le lanceur ne possède pas de journal persistant global de progression.&lt;br /&gt;
&lt;br /&gt;
Ne pas relancer le cycle depuis le clonage sur une VM existante pour terminer une étape. Ne pas relancer des étapes déjà terminées uniquement parce qu’une commande manuelle les suggère. Les suggestions suivent l’ordre théorique et ne constituent pas un inventaire de l’état de la VM.&lt;br /&gt;
&lt;br /&gt;
Codes de sortie : 0 succès, 1 annulation, 2 erreur. Le lanceur normalise les autres codes d’échec de ses sous-processus en erreur et ne poursuit pas.&lt;br /&gt;
&lt;br /&gt;
== 8. Vérifications finales ==&lt;br /&gt;
&lt;br /&gt;
Sur Saturne3, avec le VMID réellement annoncé au clonage :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
qm list&lt;br /&gt;
qm status VMID&lt;br /&gt;
qm config VMID&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remplacer VMID par l’identifiant vérifié. Contrôler le nom, les CPU, la RAM, le disque, les liens réseau et onboot selon le YAML.&lt;br /&gt;
&lt;br /&gt;
Depuis Saturne3, ouvrir la connexion et attendre l’invite de la VM :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh ajlsm@10.0.0.43&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dans MERCURE3, saisir sudo -i, attendre l’authentification et l’invite root, puis :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
hostname&lt;br /&gt;
lsblk&lt;br /&gt;
df -hT /&lt;br /&gt;
ip -br addr&lt;br /&gt;
ip route&lt;br /&gt;
resolvectl status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat vérifié pendant la recette : hostname mercure3.ajlsm.com, racine ext4 97 Gio. Les tailles disponibles évoluent avec l’utilisation. Les commandes SSH et TLS du cycle vérifient leurs propres résultats ; compléter par les tests d’accès attendus dans le réseau cible.&lt;br /&gt;
&lt;br /&gt;
== 9. Reconstruire MERCURE3 ultérieurement ==&lt;br /&gt;
&lt;br /&gt;
# Conserver le fichier mercure3-reference.yaml, le lot de scripts validé et l’identification du modèle utilisé.&lt;br /&gt;
# Comparer la référence au YAML effectivement utilisé avant reconstruction ; actualiser les changements d’infrastructure.&lt;br /&gt;
# Identifier et sauvegarder les données à conserver : le YAML n’est pas une sauvegarde de VM.&lt;br /&gt;
# Vérifier explicitement l’identité de l’ancienne VM et traiter séparément son arrêt et sa suppression volontaire. Le cycle ne détruit jamais automatiquement une VM existante.&lt;br /&gt;
# Contrôler DNS, OPNsense, Ansible et les réservations d’IP. Ne pas laisser deux VM actives avec les mêmes adresses.&lt;br /&gt;
# Valider la référence avec --check, afficher le --plan, puis lancer le cycle sur la référence après libération de la cible.&lt;br /&gt;
# Relever le nouveau VMID et effectuer les vérifications finales.&lt;br /&gt;
&lt;br /&gt;
On retrouve ainsi les paramètres de la VM, sans chercher à reproduire ses anciennes identités techniques.&lt;br /&gt;
&lt;br /&gt;
== 10. Protections et détails techniques ==&lt;br /&gt;
&lt;br /&gt;
=== 10.1. Isolation, identité et journal de personnalisation ===&lt;br /&gt;
&lt;br /&gt;
Le clone est arrêté après création, avec onboot désactivé et les interfaces isolées. Le premier démarrage s’effectue dans cet état d’isolation. Les phases système et réseau vérifient l’identité de la cible et l’UUID attendu selon leurs contrôles propres.&lt;br /&gt;
&lt;br /&gt;
La personnalisation système conserve dans l’invité :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/var/lib/ajlsm/system-personalisation/state.json&lt;br /&gt;
/var/lib/ajlsm/system-personalisation/backup/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce journal décrit la transaction d’identité, pas l’ensemble du cycle. Ne pas le supprimer pour forcer une nouvelle exécution. Après interruption, conserver les sauvegardes et examiner l’état réel avant reprise.&lt;br /&gt;
&lt;br /&gt;
La VM 515 est signalée comme hors périmètre par la documentation historique. Elle ne fait pas partie de la recette MERCURE3 et ne doit pas être ciblée par cette procédure.&lt;br /&gt;
&lt;br /&gt;
=== 10.2. Audit SSH : lecture dans la VM, écriture possible sur Saturne3 ===&lt;br /&gt;
&lt;br /&gt;
La phase --ssh-audit commence par synchroniser l’identité SSH :&lt;br /&gt;
# Lire la clé publique /etc/ssh/ssh_host_ed25519_key.pub dans la VM via l’agent QEMU.&lt;br /&gt;
# Valider le format ED25519 et sa structure binaire attendue.&lt;br /&gt;
# Lire indépendamment la clé exposée sur le réseau avec ssh-keyscan -T 8 -t ed25519.&lt;br /&gt;
# Comparer les clés : une divergence, une absence ou un format invalide provoque un refus.&lt;br /&gt;
# Après concordance seulement, sauvegarder /root/.ssh/known_hosts sur Saturne3, travailler sur une copie et remplacer le fichier avec la nouvelle entrée vérifiée pour l’IP cible.&lt;br /&gt;
# Contrôler les connexions par clé, les clés autorisées, sudo et l’état du compte ajlsm.&lt;br /&gt;
&lt;br /&gt;
Les autres entrées d’hôtes sont conservées ; le traitement retire aussi les anciennes entrées hachées correspondant à l’IP cible. Les sauvegardes utilisent le préfixe known_hosts.ajlsm-backup. dans /root/.ssh/.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;L’audit n’est donc pas entièrement sans écriture :&#039;&#039;&#039; ses lectures dans la VM sont accompagnées d’une mise à jour possible de known_hosts sur Saturne3. Ne jamais contourner une divergence en effaçant aveuglément known_hosts.&lt;br /&gt;
&lt;br /&gt;
=== 10.3. Sécurisation SSH et mot de passe ===&lt;br /&gt;
&lt;br /&gt;
--ssh-secure effectue un audit préalable, prépare un fichier SSH dédié, vérifie la syntaxe et les valeurs effectives, puis recharge SSH. Il désactive l’authentification SSH par mot de passe et conserve root par clé. Les connexions root et ajlsm par clé sont revérifiées par le code reçu.&lt;br /&gt;
&lt;br /&gt;
Le mot de passe local ajlsm reste utile pour sudo. --password-ajlsm utilise un terminal interactif et lance passwd dans la VM, avec sa double saisie masquée. Le secret n’est pas inscrit dans le YAML ni dans la ligne de commande. La procédure historique prévoit un report manuel dans le registre ODS d’administration ; appliquer les règles internes de gestion des secrets. Ne pas joindre ce registre à une documentation publique.&lt;br /&gt;
&lt;br /&gt;
=== 10.4. Certificat TLS interne et Apache ===&lt;br /&gt;
&lt;br /&gt;
--tls-apply lit le certificat /etc/ssl/ajlsm/server.crt. Si le CN et le SAN correspondent déjà au hostname attendu, la phase termine sans réinitialisation. Sinon, après confirmation, elle appelle /usr/local/sbin/ajlsm-init-tls.sh &#039;&#039;&#039;dans la VM&#039;&#039;&#039;. Ce dernier script doit être présent dans le modèle ; son contenu n’était pas inclus dans l’archive des scripts de déploiement reçue.&lt;br /&gt;
&lt;br /&gt;
Après une initialisation réussie, le module contrôle le certificat, apache2ctl configtest et systemctl is-active apache2. Ce contrôle technique d’Apache ne constitue pas une recette des VirtualHosts et des applications du projet.&lt;br /&gt;
&lt;br /&gt;
La documentation historique désigne /home/ajlsm/README, hérité de TEMPLATE3, comme README applicatif Pleade/Drupal. Le conserver séparément du README-ajlsm-deploy de l’outil de déploiement ; ne pas remplacer l’un par l’autre.&lt;br /&gt;
&lt;br /&gt;
=== 10.5. Attente réseau au premier démarrage ===&lt;br /&gt;
&lt;br /&gt;
La recette du 15 octobre signalait environ 60 secondes d’attente dans systemd-networkd-wait-online lorsque les interfaces étaient isolées. Ce constat historique n’a pas empêché l’agent QEMU ni ajlsm-clone-init de répondre. Une optimisation éventuelle du modèle reste distincte du déploiement ; ne pas désactiver le service sans vérifier ses dépendances.&lt;br /&gt;
&lt;br /&gt;
== 11. Maintenance, sauvegardes et manuel ==&lt;br /&gt;
&lt;br /&gt;
=== 11.1. Identifier les fichiers réellement exécutés ===&lt;br /&gt;
&lt;br /&gt;
La recette du 16 octobre utilise le dossier /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/. Elle ne démontre pas une mise à jour globale de /usr/local/sbin/. Toujours distinguer le lot validé et les programmes installés.&lt;br /&gt;
&lt;br /&gt;
Dans le dossier de recette :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy --help&lt;br /&gt;
./ajlsm-deploy-cycle --help&lt;br /&gt;
./ajlsm-deploy-yaml --help&lt;br /&gt;
python3 -m py_compile ajlsm-deploy ajlsm-deploy-check ajlsm-deploy-resources ajlsm-deploy-cycle ajlsm-deploy-yaml ajlsm_deploy_common.py ajlsm_deploy_rootgrow.py ajlsm_deploy_postconfig.py&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Une compilation vérifie la syntaxe, pas le bon déroulement d’une phase ni les prérequis serveur.&lt;br /&gt;
&lt;br /&gt;
=== 11.2. Sauvegarder et restaurer un lot cohérent ===&lt;br /&gt;
&lt;br /&gt;
Conserver ensemble programmes, modules et configuration de référence. Sauvegarder le lot complet avant une installation ou une correction. Exemple sur Saturne3 :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
tar -czf &amp;quot;/root/ajlsm-deploy/archives/lot-recette-$(date +%Y%m%d-%H%M%S).tar.gz&amp;quot; \&lt;br /&gt;
  -C /root/ajlsm-deploy/recettes/20261016 ajlsm-deploy-cycle&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Une restauration doit porter sur un ensemble compatible. Ne pas réinstaller uniquement ajlsm-deploy.bak-20261015 : ce fichier peut précéder les modules et phases nécessaires. L’ancienne sauvegarde et les répertoires de revue sont des références historiques à inventorier avant nettoyage.&lt;br /&gt;
&lt;br /&gt;
Ne pas supprimer INSTRUCTIONS-TEST.txt ou d’autres fichiers de /root/ajlsm-deploy-review/ sur la seule base de l’ancienne page. Leur archivage et le nettoyage ne font pas partie de cette mise à jour documentaire.&lt;br /&gt;
&lt;br /&gt;
=== 11.3. Page man ===&lt;br /&gt;
&lt;br /&gt;
La page du 15 octobre indique un manuel installé en /usr/local/man/man8/ajlsm-deploy.8 et une sauvegarde hors man8 dans /root/ajlsm-deploy-review/sauvegardes-man/. Ce sont des informations historiques, dont l’état actuel n’a pas été vérifié pendant la recette du 16 octobre.&lt;br /&gt;
&lt;br /&gt;
Pour identifier la page disponible sur Saturne3 :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man -w ajlsm-deploy&lt;br /&gt;
man 8 ajlsm-deploy&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Une page absente ne signifie pas que le script est absent : --help est l’aide intégrée de l’exécutable. Le manuel installé doit être réconcilié avec le cycle et l’assistant avant d’être considéré comme référence de cette version. En attendant, le présent guide et l’aide des fichiers du lot de recette décrivent le fonctionnement courant.&lt;br /&gt;
&lt;br /&gt;
== 12. État des validations et limites ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Date / source !! Vérification !! Portée&lt;br /&gt;
|-&lt;br /&gt;
| 15/10/2026, page historique || Déploiements initiaux jusqu’à l’activation réseau || Résultats historiques conservés ; ne décrivent pas à eux seuls le cycle actuel&lt;br /&gt;
|-&lt;br /&gt;
| 15/10/2026, page historique || Comparaison ED25519, clés divergentes ou malformées, préservation de known_hosts || Tests isolés rapportés dans la documentation reçue, non rejoués lors de cette consolidation&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, tests locaux du lot cycle || Ordre des 11 étapes, arrêt sur refus/erreur, reprise et suggestions || 8 tests réussis, incluant des sous-cas ; sous-processus des phases simulés&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, sorties Saturne3 transmises || Cycle technique complet sur un nouveau clone MERCURE3 || Terminé sans erreur signalée, extension racine incluse&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, sorties invitées transmises || SSH ajlsm, sudo, hostname et racine ext4 || Confirmés ; mercure3.ajlsm.com et 97 Gio pour /&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, tests locaux assistant || Création, correction, copie, validation et annulation || 14 tests réussis, saisies simulées&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, sortie Saturne3 transmise || Assistant --check sur mercure3.yaml || Valeurs YAML valides ; aucune écriture ni validation externe&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, vérification locale des modèles || Modèle vierge complété par l’assistant || Paramètres identiques à la référence MERCURE3 ; original intact&lt;br /&gt;
|-&lt;br /&gt;
| À réaliser || Essai réel du mécanisme de repli après échec d’activation réseau || Non confirmé ; le succès du parcours nominal ne valide pas ce scénario&lt;br /&gt;
|-&lt;br /&gt;
| À réaliser || Vérifications automatiques DNS, OPNsense, Ansible et recette applicative || Hors périmètre actuel&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le message de fin du cycle signifie que ses phases ont retourné un succès. Il ne vaut pas validation des applications ni détection de toutes les défaillances possibles. Conserver les vérifications finales et les limites propres aux phases.&lt;br /&gt;
&lt;br /&gt;
== 13. Réconciliation avec la page du 15 octobre ==&lt;br /&gt;
&lt;br /&gt;
L’original reçu est conservé intégralement dans historique/guide-20261015.mediawiki. Il sert de trace, pas de seconde procédure opérationnelle concurrente.&lt;br /&gt;
&lt;br /&gt;
Le présent document remplace les indications opérationnelles anciennes :&lt;br /&gt;
* confirmations CLONER/APPLIQUER/DEMARRER remplacées par OUI/NON ;&lt;br /&gt;
* parcours manuel seul remplacé par le choix entre mode manuel et cycle interactif ;&lt;br /&gt;
* liste des étapes incluant l’extension racine, SSH, mot de passe et TLS ;&lt;br /&gt;
* extension racine et cycle complet désormais validés sur la recette du 16 octobre ;&lt;br /&gt;
* suggestions manuelles affichant les deux commandes disponibles, sans oublier l’extension racine ;&lt;br /&gt;
* création et relecture du YAML par l’assistant, sans écraser l’original ;&lt;br /&gt;
* ajout du modèle vierge et de la référence MERCURE3 renseignée ;&lt;br /&gt;
* séparation explicite des scripts installés, du lot de recette, du manuel historique et de la future installation.&lt;br /&gt;
&lt;br /&gt;
Les détails encore utiles de l’ancienne page sur l’isolation, les transactions, ED25519, les sauvegardes, le README applicatif et les limites de validation sont repris ci-dessus. Une nouvelle mise à jour fonctionnelle doit modifier cette procédure directement plutôt que superposer une nouvelle section corrective à une ancienne procédure contradictoire.&lt;br /&gt;
&lt;br /&gt;
== 14. Suites prévues ==&lt;br /&gt;
&lt;br /&gt;
Prévoir les paramètres NFS, sites Apache2, Pleade, Drupal et Matomo dans le même YAML lorsque leurs exigences seront définies. Modifier ensemble le schéma, l’assistant, les modèles, les précontrôles, les phases et leur documentation. Documenter les références aux secrets plutôt que leurs valeurs.&lt;br /&gt;
&lt;br /&gt;
L’intégration des contrôles DNS, OPNsense et Ansible précédera une déclaration automatisée de disponibilité du projet. Le modèle actuel ne contient pas encore ces nouvelles sections.&lt;br /&gt;
&lt;br /&gt;
[[Catégorie:Infrastructure]]&lt;br /&gt;
[[Catégorie:Proxmox]]&lt;br /&gt;
[[Catégorie:Déploiement]]&lt;br /&gt;
[[Catégorie:AJLSM]]&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=D%C3%A9ploiement_technique_d%E2%80%99une_VM_AJLSM&amp;diff=6495</id>
		<title>Déploiement technique d’une VM AJLSM</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=D%C3%A9ploiement_technique_d%E2%80%99une_VM_AJLSM&amp;diff=6495"/>
		<updated>2026-10-16T16:37:31Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : /* 11.3. Page man */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= AJLSM-DEPLOY — Déploiement automatisé des VM Proxmox =&lt;br /&gt;
&lt;br /&gt;
Document consolidé au 16 octobre 2026. Cette procédure réunit la page du 15 octobre et la recette actuelle. Elle remplace leurs indications opérationnelles divergentes. L’original du 15 octobre reste archivé séparément.&lt;br /&gt;
&lt;br /&gt;
Référence technique : scripts reçus de Saturne3, puis lot de recette avec lanceur du cycle et assistant YAML.&lt;br /&gt;
&lt;br /&gt;
== 1. Périmètre et résultat de la recette ==&lt;br /&gt;
&lt;br /&gt;
Le cycle technique a été exécuté sur MERCURE3 sans erreur signalée. Les vérifications finales transmises confirment :&lt;br /&gt;
* connexion SSH avec le compte ajlsm ;&lt;br /&gt;
* élévation sudo avec le mot de passe défini pendant le cycle ;&lt;br /&gt;
* hostname mercure3.ajlsm.com ;&lt;br /&gt;
* volume racine ext4 de 97 Gio, dont 85 Gio disponibles lors du contrôle.&lt;br /&gt;
&lt;br /&gt;
Le cycle couvre le clonage, les ressources, l’initialisation du clone, l’extension de la racine, l’identité système, le réseau, SSH, le mot de passe et le certificat TLS interne.&lt;br /&gt;
&lt;br /&gt;
NFS, les configurations applicatives Apache2, Pleade, Drupal et Matomo ne font pas encore partie de ce cycle. Certains logiciels peuvent déjà être présents dans le modèle : leur présence ne constitue pas une configuration applicative du projet.&lt;br /&gt;
&lt;br /&gt;
== 2. Où exécuter les commandes ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Machine !! Rôle !! Exemple d’invite&lt;br /&gt;
|-&lt;br /&gt;
| Mac de l’administrateur || Transfert des archives par scp || Invite locale du Mac&lt;br /&gt;
|-&lt;br /&gt;
| Saturne3 || Préparation YAML, scripts Proxmox et cycle || root@Saturne3&lt;br /&gt;
|-&lt;br /&gt;
| MERCURE3 || Vérifications dans la VM || ajlsm@mercure3 ou root@mercure3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les scripts de déploiement sont exécutés sur Saturne3, pas dans MERCURE3.&lt;br /&gt;
Après « ssh ajlsm@10.0.0.43 », attendre l’invite de la VM avant de saisir les commandes suivantes.&lt;br /&gt;
Pour revenir de root@mercure3 à Saturne3 : un exit quitte sudo, puis un second exit ferme SSH.&lt;br /&gt;
&lt;br /&gt;
== 3. Organisation des fichiers ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/root/ajlsm-deploy/&lt;br /&gt;
  archives/                         Archives reçues, conservées comme références&lt;br /&gt;
  recettes/20261016/&lt;br /&gt;
    ajlsm-deploy-cycle/             Lot technique validé et assistant ajouté&lt;br /&gt;
    ajlsm-deploy-assistant/         Distribution de l’assistant et tests&lt;br /&gt;
    ajlsm-deploy-documentation/     Présent guide et modèles YAML&lt;br /&gt;
&lt;br /&gt;
/etc/ajlsm/deploy/projets/mercure3.yaml   Configuration actuellement utilisée&lt;br /&gt;
/usr/local/sbin/                        Scripts installés antérieurement&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le lot de recette contient ajlsm-deploy, ajlsm-deploy-check, ajlsm-deploy-resources, ajlsm-deploy-cycle et les modules ajlsm_deploy_common.py, ajlsm_deploy_rootgrow.py et ajlsm_deploy_postconfig.py. L’assistant ajlsm-deploy-yaml a été ajouté à ce même dossier.&lt;br /&gt;
&lt;br /&gt;
Conserver exécutables et modules ensemble. Utiliser les chemins ./ depuis le dossier de recette pour ne pas appeler une ancienne version de /usr/local/sbin.&lt;br /&gt;
Les anciennes archives « ajlsm-deploy-revise » et « correction-suggestions » ne sont pas la référence courante : elles précèdent les phases supplémentaires reçues dans l’archive serveur.&lt;br /&gt;
&lt;br /&gt;
Prérequis : Python 3.9 ou supérieur, PyYAML 6, outils Proxmox sur le nœud cible et prérequis du modèle AJLSM. Les phases invitées utilisent notamment l’agent QEMU, ajlsm-clone-init, Python, systemd et Netplan. L’extension actuelle cible ext4/LVM sur /dev/sda3, avec un seul PV et un seul LV.&lt;br /&gt;
&lt;br /&gt;
== 4. Les deux fichiers de préconfiguration ==&lt;br /&gt;
&lt;br /&gt;
=== 4.1. projet-vierge.yaml ===&lt;br /&gt;
&lt;br /&gt;
Ce modèle reprend toute la structure actuelle sans valeur opérationnelle préremplie. Chaque champ doit être renseigné. Seul proxmox.vmid peut rester null : il signifie alors attribution automatique.&lt;br /&gt;
&lt;br /&gt;
Le modèle comporte deux interfaces dont les valeurs sont null. Adapter le nombre d’interfaces avant la saisie si nécessaire. Pour déterminer ce nombre par les questions de l’assistant, utiliser plutôt le mode --new.&lt;br /&gt;
&lt;br /&gt;
Un modèle vierge est volontairement refusé par --check. Il ne doit jamais être passé directement au lanceur du cycle.&lt;br /&gt;
&lt;br /&gt;
=== 4.2. mercure3-reference.yaml ===&lt;br /&gt;
&lt;br /&gt;
Ce fichier conserve les valeurs du projet validé : modèle 506 sur Saturne3, nom MERCURE3, 8 vCPU, 24576 Mio de RAM maximale, 16384 Mio minimale, disque 100 Gio, extension racine activée et paramètres réseau du projet.&lt;br /&gt;
&lt;br /&gt;
Il permet de reconstruire une nouvelle VM avec la même configuration technique si le modèle, le stockage, les bridges et les préparatifs externes sont toujours disponibles. Il ne sauvegarde ni les données de l’ancienne VM, ni ses UUID, machine-id, clés hôte SSH ou mots de passe. Ces identités sont traitées par le cycle et ne sont pas à recopier.&lt;br /&gt;
&lt;br /&gt;
Avec vmid: null, le VMID de remplacement peut différer de celui de l’ancienne VM. Le VMID 505 observé pendant la recette n’est pas une réservation permanente.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ne pas lancer cette référence tant que MERCURE3 existe encore.&#039;&#039;&#039; Le clonage refuse un nom déjà présent. Pour tester une deuxième VM en parallèle, définir un autre nom, hostname, des IP distinctes et préparer DNS/OPNsense/Ansible en conséquence.&lt;br /&gt;
&lt;br /&gt;
=== 4.3. Valeurs acceptées ===&lt;br /&gt;
&lt;br /&gt;
* projet.environnement et tags : interne, client, prod. Les tags sont une liste sans doublons ; [] est admis.&lt;br /&gt;
* CPU, mémoire et taille du disque : entiers strictement positifs ; mémoire minimale inférieure ou égale à la maximale.&lt;br /&gt;
* Booléens : utiliser true ou false sans guillemets.&lt;br /&gt;
* Interfaces Proxmox : net suivi de chiffres ; interfaces invitées : ens suivi de chiffres.&lt;br /&gt;
* Adresses d’interfaces : IPv4/CIDR. Loopback : IPv4/32. Passerelle et DNS : IPv4 sans préfixe.&lt;br /&gt;
* Passerelle : interface déclarée et adresse appartenant à son sous-réseau, distincte des adresses de la VM.&lt;br /&gt;
* Hostname : nom DNS en minuscules.&lt;br /&gt;
* Serveur, bridge et stockage : valeurs adaptées à l’infrastructure ; aucune liste fermée inventée.&lt;br /&gt;
&lt;br /&gt;
Les clés inconnues ou répétées sont refusées. Ne pas ajouter de sections applicatives avant l’évolution coordonnée du schéma et des scripts. Ne pas utiliser [à renseigner] : les crochets créent une liste YAML.&lt;br /&gt;
&lt;br /&gt;
== 5. Préparer et valider le YAML ==&lt;br /&gt;
&lt;br /&gt;
Sur Saturne3, se placer dans le lot de recette :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5.1. Vérifier un fichier existant sans le modifier ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml /etc/ajlsm/deploy/projets/mercure3.yaml --check&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le message de succès signifie que les valeurs et leur cohérence locale sont conformes. Il ne certifie pas la préparation des services externes.&lt;br /&gt;
&lt;br /&gt;
Voici un exemple : &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;projet:&lt;br /&gt;
  code: mercure3&lt;br /&gt;
  nom: MERCURE3&lt;br /&gt;
  environnement: interne&lt;br /&gt;
&lt;br /&gt;
proxmox:&lt;br /&gt;
  serveur: Saturne3&lt;br /&gt;
  template_vmid: 506&lt;br /&gt;
  vmid: null&lt;br /&gt;
  nom_vm: MERCURE3&lt;br /&gt;
&lt;br /&gt;
  cpu:&lt;br /&gt;
    sockets: 1&lt;br /&gt;
    cores: 8&lt;br /&gt;
&lt;br /&gt;
  memoire:&lt;br /&gt;
    maximale_mib: 24576&lt;br /&gt;
    minimale_mib: 16384&lt;br /&gt;
&lt;br /&gt;
  disque_systeme:&lt;br /&gt;
    stockage: local-zfs&lt;br /&gt;
    taille_gib: 100&lt;br /&gt;
    etendre_volume_racine: true&lt;br /&gt;
&lt;br /&gt;
  demarrage_auto: true&lt;br /&gt;
&lt;br /&gt;
  tags:&lt;br /&gt;
    - interne&lt;br /&gt;
&lt;br /&gt;
systeme:&lt;br /&gt;
  hostname: mercure3.ajlsm.com&lt;br /&gt;
&lt;br /&gt;
reseau:&lt;br /&gt;
  interfaces:&lt;br /&gt;
    - nom: net0&lt;br /&gt;
      bridge: vmbr2&lt;br /&gt;
      systeme: ens18&lt;br /&gt;
      ipv4: 10.0.0.43/24&lt;br /&gt;
&lt;br /&gt;
    - nom: net1&lt;br /&gt;
      bridge: vmbr1&lt;br /&gt;
      systeme: ens19&lt;br /&gt;
      ipv4: 192.168.123.27/24&lt;br /&gt;
&lt;br /&gt;
  loopback:&lt;br /&gt;
    ipv4: 51.83.117.113/32&lt;br /&gt;
&lt;br /&gt;
  passerelle:&lt;br /&gt;
    ipv4: 10.0.0.4&lt;br /&gt;
    interface: ens18&lt;br /&gt;
&lt;br /&gt;
  dns:&lt;br /&gt;
    - 10.0.0.4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5.2. Compléter le modèle vierge ===&lt;br /&gt;
&lt;br /&gt;
Après extraction du présent lot documentaire :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml \&lt;br /&gt;
  /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-documentation/projet-vierge.yaml \&lt;br /&gt;
  --output /root/ajlsm-deploy/recettes/20261016/nouveau-projet.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Toutes les valeurs obligatoires seront demandées. Pour saisir de nouveau le projet MERCURE3, consulter mercure3-reference.yaml comme fiche de paramètres, sans lancer de déploiement.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;# Préconfiguration AJLSM vierge : aucune valeur d’infrastructure préremplie.&lt;br /&gt;
# Compléter avec ajlsm-deploy-yaml ; ne pas déployer ce modèle tel quel.&lt;br /&gt;
# null = champ à renseigner, SAUF proxmox.vmid où null = attribution automatique.&lt;br /&gt;
# Les crochets [à renseigner] sont interdits : ils représenteraient une liste YAML.&lt;br /&gt;
# Deux interfaces sont proposées : adapter leur nombre avant la saisie.&lt;br /&gt;
projet:&lt;br /&gt;
  code: null  # Obligatoire : minuscules/chiffres, tiret et souligné ; ex. mercure3.&lt;br /&gt;
  nom: null  # Obligatoire : nom lisible du projet.&lt;br /&gt;
  environnement: null  # Liste fermée : interne, client, prod.&lt;br /&gt;
&lt;br /&gt;
proxmox:&lt;br /&gt;
  serveur: null  # Obligatoire : nom du nœud Proxmox, ex. Saturne3.&lt;br /&gt;
  template_vmid: null  # Obligatoire : entier positif, VM modèle existante et arrêtée.&lt;br /&gt;
  vmid: null  # Automatique ; sinon entier positif différent de template_vmid.&lt;br /&gt;
  nom_vm: null  # Obligatoire : nom de VM, lettres/chiffres/point/tiret.&lt;br /&gt;
  cpu:&lt;br /&gt;
    sockets: null  # Obligatoire : entier positif.&lt;br /&gt;
    cores: null  # Obligatoire : entier positif ; vCPU = sockets × cores.&lt;br /&gt;
  memoire:&lt;br /&gt;
    maximale_mib: null  # Obligatoire : entier positif, en Mio.&lt;br /&gt;
    minimale_mib: null  # Obligatoire : entier positif, inférieur ou égal au maximum.&lt;br /&gt;
  disque_systeme:&lt;br /&gt;
    stockage: null  # Obligatoire : identifiant de stockage Proxmox existant.&lt;br /&gt;
    taille_gib: null  # Obligatoire : entier positif en Gio ; aucune réduction de disque.&lt;br /&gt;
    etendre_volume_racine: null  # Obligatoire : true ou false ; active la phase racine.&lt;br /&gt;
  demarrage_auto: null  # Obligatoire : true ou false ; appliqué à l’activation réseau.&lt;br /&gt;
  tags: null  # Obligatoire : liste ; interne/client/prod uniquement, sans doublons ; [] admis.&lt;br /&gt;
&lt;br /&gt;
systeme:&lt;br /&gt;
  hostname: null  # Obligatoire : nom DNS en minuscules ; vérifier sa déclaration en amont.&lt;br /&gt;
&lt;br /&gt;
reseau:&lt;br /&gt;
  interfaces:&lt;br /&gt;
    - nom: null  # Obligatoire : net suivi de chiffres, conforme à la VM modèle.&lt;br /&gt;
      bridge: null  # Obligatoire : bridge existant, au plus 15 caractères.&lt;br /&gt;
      systeme: null  # Obligatoire : ens suivi de chiffres, conforme au modèle actuel.&lt;br /&gt;
      ipv4: null  # Obligatoire : IPv4/CIDR, ex. 10.0.0.43/24 ; adresse unique.&lt;br /&gt;
    - nom: null&lt;br /&gt;
      bridge: null&lt;br /&gt;
      systeme: null&lt;br /&gt;
      ipv4: null&lt;br /&gt;
  loopback:&lt;br /&gt;
    ipv4: null  # Obligatoire : IPv4 avec préfixe /32, distincte des interfaces.&lt;br /&gt;
  passerelle:&lt;br /&gt;
    ipv4: null  # Obligatoire : IPv4 seule, dans le sous-réseau de son interface.&lt;br /&gt;
    interface: null  # Obligatoire : un des noms systeme déclarés ci-dessus.&lt;br /&gt;
  dns: null  # Obligatoire : liste non vide d’IPv4 sans préfixe, ex. [10.0.0.4].&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5.3. Créer sans modèle ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml /root/ajlsm-deploy/recettes/20261016/nouveau-projet.yaml --new&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette commande est une alternative à la précédente : le chemin doit être inexistant. L’assistant pose les questions, y compris le nombre d’interfaces, sans reprendre implicitement les valeurs de MERCURE3.&lt;br /&gt;
&lt;br /&gt;
=== 5.4. Revoir un projet renseigné ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml /etc/ajlsm/deploy/projets/mercure3.yaml --review \&lt;br /&gt;
  --output /root/ajlsm-deploy/recettes/20261016/mercure3-relecture.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Entrée conserve une valeur existante valide.&lt;br /&gt;
* ANNULER, Ctrl-C ou fin d’entrée abandonnent sans enregistrer.&lt;br /&gt;
* Tags et DNS sont saisis séparés par des virgules ; [] ou aucun signifie tags vides.&lt;br /&gt;
* Saisir auto ou null pour un VMID automatique.&lt;br /&gt;
* Après une incohérence, donner le chemin du champ à corriger ; ? affiche les chemins.&lt;br /&gt;
* Le résumé complet est présenté avant confirmation OUI/NON d’enregistrement.&lt;br /&gt;
&lt;br /&gt;
L’original reste intact, avec ses commentaires. La copie est réécrite en YAML, sans reprise des commentaires. Aucun fichier existant n’est écrasé. Si une destination existe, choisir un nouveau nom avec --output.&lt;br /&gt;
&lt;br /&gt;
=== 5.5. Préparatifs externes ===&lt;br /&gt;
&lt;br /&gt;
Avant une création, vérifier séparément la réservation des IP, les déclarations DNS, les règles/routes/NAT nécessaires dans OPNsense et l’inventaire ou les préparatifs Ansible. Ne pas inscrire de mots de passe dans le YAML ; conserver les secrets dans le dispositif prévu pour leur gestion.&lt;br /&gt;
&lt;br /&gt;
L’assistant actuel ne vérifie pas automatiquement ces services et ne marque pas un projet « prêt à déployer » sur cette seule base. Leur intégration reste à réaliser.&lt;br /&gt;
&lt;br /&gt;
Le contrôle Proxmox autonome examine notamment le modèle, ses ressources, le stockage et les bridges. Il concerne une nouvelle création et peut refuser un projet déjà déployé :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-check /chemin/vers/projet.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 6. Afficher le plan puis lancer le cycle ==&lt;br /&gt;
&lt;br /&gt;
=== 6.1. Plan sans exécution ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /chemin/vers/projet.yaml --plan&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le plan valide le YAML et affiche les commandes, sans exécuter les phases ni vérifier l’infrastructure. Il doit contenir les 11 étapes, toutes dans le dossier de recette.&lt;br /&gt;
&lt;br /&gt;
=== 6.2. Cycle réel pour une nouvelle VM ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /chemin/vers/projet.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le lanceur exécute les phases réelles, sans simulation automatique. Il attend seulement les confirmations, les saisies nécessaires et la fin de chaque commande. Il s’arrête sur refus ou erreur. Il ne répond pas à la place de l’administrateur et ne capture pas les mots de passe.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! N° !! Étape !! Commande réelle !! Simulation facultative&lt;br /&gt;
|-&lt;br /&gt;
| 1 || Clonage || --clone || --dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Ressources || --configure-resources || --resources-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Premier démarrage isolé || --first-boot-apply || --first-boot-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Extension partition/LVM/ext4 || --root-grow-apply || --root-grow-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Identité système || --system-apply || --system-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Préparation Netplan || --network-apply || --network-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Activation réseau || --network-enable || --network-enable-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Audit SSH || --ssh-audit || Aucune option dédiée&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Sécurisation SSH || --ssh-secure || Aucune option dédiée&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Mot de passe ajlsm || --password-ajlsm || Aucune option dédiée&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Certificat TLS interne || --tls-apply || Aucune option dédiée&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
L’extension racine est indispensable quand etendre_volume_racine vaut true. Agrandir le disque Proxmox ne suffit pas : la partition, le PV LVM, le LV et ext4 doivent aussi être étendus. Cette phase doit figurer après le premier démarrage, avant la personnalisation système. Avec false, la phase annonce sa désactivation.&lt;br /&gt;
&lt;br /&gt;
Le démarrage et la personnalisation se font réseau isolé. Netplan est préparé avant activation des liens. La phase d’activation contrôle le réseau et applique demarrage_auto.&lt;br /&gt;
&lt;br /&gt;
Le certificat TLS interne ne constitue pas, à lui seul, une configuration des applications du projet ou un certificat publiquement reconnu.&lt;br /&gt;
&lt;br /&gt;
=== 6.3. Mode manuel ===&lt;br /&gt;
&lt;br /&gt;
Chaque phase peut être lancée séparément avec ./ajlsm-deploy suivi du YAML et de son option. Après succès, le lot courant affiche deux lignes pour l’étape suivante : Simulation et Exécution. Si la simulation n’existe pas, il le signale. Aucune suggestion n’est exécutée automatiquement.&lt;br /&gt;
&lt;br /&gt;
Les simulations peuvent consulter l’invité et émettre des sondes ARP selon la phase : elles ne sont pas toutes des contrôles hors ligne. L’absence de réponse ARP ne remplace pas la réservation des adresses dans l’inventaire réseau.&lt;br /&gt;
&lt;br /&gt;
== 7. Erreur, annulation et reprise ==&lt;br /&gt;
&lt;br /&gt;
Conserver la sortie complète et diagnostiquer la phase fautive avant de reprendre. Une phase peut être partiellement effectuée ; le lanceur n’effectue ni suppression de VM ni restauration globale automatique.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /chemin/vers/projet.yaml --from extension-racine&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--from inclut l’étape indiquée et saute les précédentes à la demande de l’administrateur. Il ne certifie pas leur état. Les contrôles propres aux phases restent actifs. Le lanceur ne possède pas de journal persistant global de progression.&lt;br /&gt;
&lt;br /&gt;
Ne pas relancer le cycle depuis le clonage sur une VM existante pour terminer une étape. Ne pas relancer des étapes déjà terminées uniquement parce qu’une commande manuelle les suggère. Les suggestions suivent l’ordre théorique et ne constituent pas un inventaire de l’état de la VM.&lt;br /&gt;
&lt;br /&gt;
Codes de sortie : 0 succès, 1 annulation, 2 erreur. Le lanceur normalise les autres codes d’échec de ses sous-processus en erreur et ne poursuit pas.&lt;br /&gt;
&lt;br /&gt;
== 8. Vérifications finales ==&lt;br /&gt;
&lt;br /&gt;
Sur Saturne3, avec le VMID réellement annoncé au clonage :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
qm list&lt;br /&gt;
qm status VMID&lt;br /&gt;
qm config VMID&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remplacer VMID par l’identifiant vérifié. Contrôler le nom, les CPU, la RAM, le disque, les liens réseau et onboot selon le YAML.&lt;br /&gt;
&lt;br /&gt;
Depuis Saturne3, ouvrir la connexion et attendre l’invite de la VM :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh ajlsm@10.0.0.43&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dans MERCURE3, saisir sudo -i, attendre l’authentification et l’invite root, puis :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
hostname&lt;br /&gt;
lsblk&lt;br /&gt;
df -hT /&lt;br /&gt;
ip -br addr&lt;br /&gt;
ip route&lt;br /&gt;
resolvectl status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat vérifié pendant la recette : hostname mercure3.ajlsm.com, racine ext4 97 Gio. Les tailles disponibles évoluent avec l’utilisation. Les commandes SSH et TLS du cycle vérifient leurs propres résultats ; compléter par les tests d’accès attendus dans le réseau cible.&lt;br /&gt;
&lt;br /&gt;
== 9. Reconstruire MERCURE3 ultérieurement ==&lt;br /&gt;
&lt;br /&gt;
# Conserver le fichier mercure3-reference.yaml, le lot de scripts validé et l’identification du modèle utilisé.&lt;br /&gt;
# Comparer la référence au YAML effectivement utilisé avant reconstruction ; actualiser les changements d’infrastructure.&lt;br /&gt;
# Identifier et sauvegarder les données à conserver : le YAML n’est pas une sauvegarde de VM.&lt;br /&gt;
# Vérifier explicitement l’identité de l’ancienne VM et traiter séparément son arrêt et sa suppression volontaire. Le cycle ne détruit jamais automatiquement une VM existante.&lt;br /&gt;
# Contrôler DNS, OPNsense, Ansible et les réservations d’IP. Ne pas laisser deux VM actives avec les mêmes adresses.&lt;br /&gt;
# Valider la référence avec --check, afficher le --plan, puis lancer le cycle sur la référence après libération de la cible.&lt;br /&gt;
# Relever le nouveau VMID et effectuer les vérifications finales.&lt;br /&gt;
&lt;br /&gt;
On retrouve ainsi les paramètres de la VM, sans chercher à reproduire ses anciennes identités techniques.&lt;br /&gt;
&lt;br /&gt;
== 10. Protections et détails techniques ==&lt;br /&gt;
&lt;br /&gt;
=== 10.1. Isolation, identité et journal de personnalisation ===&lt;br /&gt;
&lt;br /&gt;
Le clone est arrêté après création, avec onboot désactivé et les interfaces isolées. Le premier démarrage s’effectue dans cet état d’isolation. Les phases système et réseau vérifient l’identité de la cible et l’UUID attendu selon leurs contrôles propres.&lt;br /&gt;
&lt;br /&gt;
La personnalisation système conserve dans l’invité :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/var/lib/ajlsm/system-personalisation/state.json&lt;br /&gt;
/var/lib/ajlsm/system-personalisation/backup/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce journal décrit la transaction d’identité, pas l’ensemble du cycle. Ne pas le supprimer pour forcer une nouvelle exécution. Après interruption, conserver les sauvegardes et examiner l’état réel avant reprise.&lt;br /&gt;
&lt;br /&gt;
La VM 515 est signalée comme hors périmètre par la documentation historique. Elle ne fait pas partie de la recette MERCURE3 et ne doit pas être ciblée par cette procédure.&lt;br /&gt;
&lt;br /&gt;
=== 10.2. Audit SSH : lecture dans la VM, écriture possible sur Saturne3 ===&lt;br /&gt;
&lt;br /&gt;
La phase --ssh-audit commence par synchroniser l’identité SSH :&lt;br /&gt;
# Lire la clé publique /etc/ssh/ssh_host_ed25519_key.pub dans la VM via l’agent QEMU.&lt;br /&gt;
# Valider le format ED25519 et sa structure binaire attendue.&lt;br /&gt;
# Lire indépendamment la clé exposée sur le réseau avec ssh-keyscan -T 8 -t ed25519.&lt;br /&gt;
# Comparer les clés : une divergence, une absence ou un format invalide provoque un refus.&lt;br /&gt;
# Après concordance seulement, sauvegarder /root/.ssh/known_hosts sur Saturne3, travailler sur une copie et remplacer le fichier avec la nouvelle entrée vérifiée pour l’IP cible.&lt;br /&gt;
# Contrôler les connexions par clé, les clés autorisées, sudo et l’état du compte ajlsm.&lt;br /&gt;
&lt;br /&gt;
Les autres entrées d’hôtes sont conservées ; le traitement retire aussi les anciennes entrées hachées correspondant à l’IP cible. Les sauvegardes utilisent le préfixe known_hosts.ajlsm-backup. dans /root/.ssh/.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;L’audit n’est donc pas entièrement sans écriture :&#039;&#039;&#039; ses lectures dans la VM sont accompagnées d’une mise à jour possible de known_hosts sur Saturne3. Ne jamais contourner une divergence en effaçant aveuglément known_hosts.&lt;br /&gt;
&lt;br /&gt;
=== 10.3. Sécurisation SSH et mot de passe ===&lt;br /&gt;
&lt;br /&gt;
--ssh-secure effectue un audit préalable, prépare un fichier SSH dédié, vérifie la syntaxe et les valeurs effectives, puis recharge SSH. Il désactive l’authentification SSH par mot de passe et conserve root par clé. Les connexions root et ajlsm par clé sont revérifiées par le code reçu.&lt;br /&gt;
&lt;br /&gt;
Le mot de passe local ajlsm reste utile pour sudo. --password-ajlsm utilise un terminal interactif et lance passwd dans la VM, avec sa double saisie masquée. Le secret n’est pas inscrit dans le YAML ni dans la ligne de commande. La procédure historique prévoit un report manuel dans le registre ODS d’administration ; appliquer les règles internes de gestion des secrets. Ne pas joindre ce registre à une documentation publique.&lt;br /&gt;
&lt;br /&gt;
=== 10.4. Certificat TLS interne et Apache ===&lt;br /&gt;
&lt;br /&gt;
--tls-apply lit le certificat /etc/ssl/ajlsm/server.crt. Si le CN et le SAN correspondent déjà au hostname attendu, la phase termine sans réinitialisation. Sinon, après confirmation, elle appelle /usr/local/sbin/ajlsm-init-tls.sh &#039;&#039;&#039;dans la VM&#039;&#039;&#039;. Ce dernier script doit être présent dans le modèle ; son contenu n’était pas inclus dans l’archive des scripts de déploiement reçue.&lt;br /&gt;
&lt;br /&gt;
Après une initialisation réussie, le module contrôle le certificat, apache2ctl configtest et systemctl is-active apache2. Ce contrôle technique d’Apache ne constitue pas une recette des VirtualHosts et des applications du projet.&lt;br /&gt;
&lt;br /&gt;
La documentation historique désigne /home/ajlsm/README, hérité de TEMPLATE3, comme README applicatif Pleade/Drupal. Le conserver séparément du README-ajlsm-deploy de l’outil de déploiement ; ne pas remplacer l’un par l’autre.&lt;br /&gt;
&lt;br /&gt;
=== 10.5. Attente réseau au premier démarrage ===&lt;br /&gt;
&lt;br /&gt;
La recette du 15 octobre signalait environ 60 secondes d’attente dans systemd-networkd-wait-online lorsque les interfaces étaient isolées. Ce constat historique n’a pas empêché l’agent QEMU ni ajlsm-clone-init de répondre. Une optimisation éventuelle du modèle reste distincte du déploiement ; ne pas désactiver le service sans vérifier ses dépendances.&lt;br /&gt;
&lt;br /&gt;
== 11. Maintenance, sauvegardes et manuel ==&lt;br /&gt;
&lt;br /&gt;
=== 11.1. Identifier les fichiers réellement exécutés ===&lt;br /&gt;
&lt;br /&gt;
La recette du 16 octobre utilise le dossier /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/. Elle ne démontre pas une mise à jour globale de /usr/local/sbin/. Toujours distinguer le lot validé et les programmes installés.&lt;br /&gt;
&lt;br /&gt;
Dans le dossier de recette :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy --help&lt;br /&gt;
./ajlsm-deploy-cycle --help&lt;br /&gt;
./ajlsm-deploy-yaml --help&lt;br /&gt;
python3 -m py_compile ajlsm-deploy ajlsm-deploy-check ajlsm-deploy-resources ajlsm-deploy-cycle ajlsm-deploy-yaml ajlsm_deploy_common.py ajlsm_deploy_rootgrow.py ajlsm_deploy_postconfig.py&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Une compilation vérifie la syntaxe, pas le bon déroulement d’une phase ni les prérequis serveur.&lt;br /&gt;
&lt;br /&gt;
=== 11.2. Sauvegarder et restaurer un lot cohérent ===&lt;br /&gt;
&lt;br /&gt;
Conserver ensemble programmes, modules et configuration de référence. Sauvegarder le lot complet avant une installation ou une correction. Exemple sur Saturne3 :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
tar -czf &amp;quot;/root/ajlsm-deploy/archives/lot-recette-$(date +%Y%m%d-%H%M%S).tar.gz&amp;quot; \&lt;br /&gt;
  -C /root/ajlsm-deploy/recettes/20261016 ajlsm-deploy-cycle&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Une restauration doit porter sur un ensemble compatible. Ne pas réinstaller uniquement ajlsm-deploy.bak-20261015 : ce fichier peut précéder les modules et phases nécessaires. L’ancienne sauvegarde et les répertoires de revue sont des références historiques à inventorier avant nettoyage.&lt;br /&gt;
&lt;br /&gt;
Ne pas supprimer INSTRUCTIONS-TEST.txt ou d’autres fichiers de /root/ajlsm-deploy-review/ sur la seule base de l’ancienne page. Leur archivage et le nettoyage ne font pas partie de cette mise à jour documentaire.&lt;br /&gt;
&lt;br /&gt;
=== 11.3. Page man ===&lt;br /&gt;
&lt;br /&gt;
La page du 15 octobre indique un manuel installé en /usr/local/man/man8/ajlsm-deploy.8 et une sauvegarde hors man8 dans /root/ajlsm-deploy-review/sauvegardes-man/. Ce sont des informations historiques, dont l’état actuel n’a pas été vérifié pendant la recette du 16 octobre.&lt;br /&gt;
&lt;br /&gt;
Pour identifier la page disponible sur Saturne3 :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man -w ajlsm-deploy&lt;br /&gt;
man 8 ajlsm-deploy&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Une page absente ne signifie pas que le script est absent : --help est l’aide intégrée de l’exécutable. Le manuel installé doit être réconcilié avec le cycle et l’assistant avant d’être considéré comme référence de cette version. En attendant, le présent guide et l’aide des fichiers du lot de recette décrivent le fonctionnement courant.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;Last login: Fri Oct 16 15:21:06 on ttys000&lt;br /&gt;
jlarvers@MacBook-Pro ~ % ssh saturne3&lt;br /&gt;
Linux Saturne3 7.0.14-23-pve #1 SMP PREEMPT_DYNAMIC PMX 7.0.14-23 (2026-10-07T20:25Z) x86_64&lt;br /&gt;
&lt;br /&gt;
The programs included with the Debian GNU/Linux system are free software;&lt;br /&gt;
the exact distribution terms for each program are described in the&lt;br /&gt;
individual files in /usr/share/doc/*/copyright.&lt;br /&gt;
&lt;br /&gt;
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent&lt;br /&gt;
permitted by applicable law.&lt;br /&gt;
Last login: Fri Oct 16 09:46:02 2026 from 109.190.129.96&lt;br /&gt;
root@Saturne3:~# qm status 505&lt;br /&gt;
qm config 505&lt;br /&gt;
status: running&lt;br /&gt;
agent: 1&lt;br /&gt;
balloon: 16384&lt;br /&gt;
boot: order=scsi0;net0&lt;br /&gt;
cores: 8&lt;br /&gt;
cpu: x86-64-v2-AES&lt;br /&gt;
memory: 24576&lt;br /&gt;
meta: creation-qemu=11.0.0,ctime=1779439732&lt;br /&gt;
name: MERCURE3&lt;br /&gt;
net0: virtio=BC:24:11:D5:B4:C2,bridge=vmbr2,firewall=1,link_down=0&lt;br /&gt;
net1: virtio=BC:24:11:E8:F0:BD,bridge=vmbr1,firewall=1,link_down=0&lt;br /&gt;
numa: 0&lt;br /&gt;
onboot: 1&lt;br /&gt;
ostype: l26&lt;br /&gt;
scsi0: local-zfs:vm-505-disk-0,iothread=1,size=100G&lt;br /&gt;
scsihw: virtio-scsi-single&lt;br /&gt;
smbios1: uuid=f47653e5-e87f-4765-bd41-46bb2eaac990&lt;br /&gt;
sockets: 1&lt;br /&gt;
tags: interne&lt;br /&gt;
vmgenid: d0cfe3f4-9292-4c03-81d9-662131e54889&lt;br /&gt;
root@Saturne3:~# qm set 505 --onboot 0&lt;br /&gt;
qm shutdown 505 --timeout 120&lt;br /&gt;
qm status 505&lt;br /&gt;
update VM 505: -onboot 0&lt;br /&gt;
status: stopped&lt;br /&gt;
root@Saturne3:~# PROJET_YAML=/etc/ajlsm/deploy/projets/mercure3.yaml&lt;br /&gt;
root@Saturne3:~# ./ajlsm-deploy &amp;quot;$PROJET_YAML&amp;quot; --clone&lt;br /&gt;
-bash: ./ajlsm-deploy: No such file or directory&lt;br /&gt;
root@Saturne3:~# history&lt;br /&gt;
    1  Ne pas lancer toutes les phases dans un script ou une chaîne de&lt;br /&gt;
    2  commandes.&lt;br /&gt;
    3  PHASE 1 - CLONAGE&lt;br /&gt;
    4  Simulation :&lt;br /&gt;
    5      ajlsm-deploy &amp;quot;$PROJET&amp;quot; --dry-run&lt;br /&gt;
    6  Clonage :&lt;br /&gt;
    7      ajlsm-deploy &amp;quot;$PROJET&amp;quot; --clone&lt;br /&gt;
    8  Le clone est créé sans démarrage.&lt;br /&gt;
    9  Vérifier le VMID réellement attribué.&lt;br /&gt;
   10  PHASE 2 - CONFIGURATION DES RESSOURCES&lt;br /&gt;
   11  Simulation :&lt;br /&gt;
   12      ajlsm-deploy &amp;quot;$PROJET&amp;quot; --resources-dry-run&lt;br /&gt;
   13  Application :&lt;br /&gt;
   14      ajlsm-deploy &amp;quot;$PROJET&amp;quot; --configure-resources&lt;br /&gt;
   15  Configuration des ressources CPU, RAM et disque.&lt;br /&gt;
   16  L&#039;agrandissement du disque Proxmox ne suffit pas à agrandir le&lt;br /&gt;
   17  système de fichiers à l&#039;intérieur de la VM.&lt;br /&gt;
   18  PHASE 3 - PREMIER DEMARRAGE ISOLE&lt;br /&gt;
   19  Simulation :&lt;br /&gt;
   20      ajlsm-deploy &amp;quot;$PROJET&amp;quot; --first-boot-dry-run&lt;br /&gt;
   21  Application :&lt;br /&gt;
   22      ajlsm-deploy &amp;quot;$PROJET&amp;quot; --first-boot-apply&lt;br /&gt;
   23  Le clone démarre avec ses interfaces réseau isolées.&lt;br /&gt;
   24  Le programme contrôle notamment l&#039;agent QEMU et l&#039;initialisation&lt;br /&gt;
   25  du clone.&lt;br /&gt;
   26  Ne pas activer manuellement les interfaces réseau.&lt;br /&gt;
   27  PHASE 4 - EXTENSION DU VOLUME RACINE&lt;br /&gt;
   28  Simulation :&lt;br /&gt;
   29      ajlsm-deploy &amp;quot;$PROJET&amp;quot; --root-grow-dry-run&lt;br /&gt;
   30  Application :&lt;br /&gt;
   31      ajlsm-deploy &amp;quot;$PROJET&amp;quot; --root-grow-apply&lt;br /&gt;
   32  Cette phase étend la partition, le volume LVM et le système de&lt;br /&gt;
   33  fichiers ext4 selon la configuration prévue.&lt;br /&gt;
   34  Elle doit être effectuée après le premier démarrage et avant la&lt;br /&gt;
   35  personnalisation système.&lt;br /&gt;
   36  En cas d&#039;erreur, ne pas poursuivre sans diagnostic.&lt;br /&gt;
   37  PHASE 5 - PERSONNALISATION SYSTEME&lt;br /&gt;
   38  Simulation :&lt;br /&gt;
   39      ajlsm-deploy &amp;quot;$PROJET&amp;quot; --system-dry-run&lt;br /&gt;
   40  Application :&lt;br /&gt;
   41      ajlsm-deploy &amp;quot;$PROJET&amp;quot; --system-apply&lt;br /&gt;
   42  Personnalisation de l&#039;identité système, notamment du hostname&lt;br /&gt;
   43  et du machine-id.&lt;br /&gt;
   44  La VM reste isolée du réseau.&lt;br /&gt;
   45  Les informations de transaction sont conservées dans :&lt;br /&gt;
   46      /var/lib/ajlsm/system-personalisation/&lt;br /&gt;
   47  Ne pas supprimer ces informations pour forcer une nouvelle opération.&lt;br /&gt;
   48  PHASE 6 - CONFIGURATION NETPLAN&lt;br /&gt;
   49  Simulation :&lt;br /&gt;
   50      ajlsm-deploy &amp;quot;$PROJET&amp;quot; --network-dry-run&lt;br /&gt;
   51  Application :&lt;br /&gt;
   52      ajlsm-deploy &amp;quot;$PROJET&amp;quot; --network-apply&lt;br /&gt;
   53  Préparation de Netplan et vérification de sa génération.&lt;br /&gt;
   54  Les interfaces Proxmox restent isolées.&lt;br /&gt;
   55  PHASE 7 - ACTIVATION DU RESEAU&lt;br /&gt;
   56  Simulation :&lt;br /&gt;
   57      ajlsm-deploy &amp;quot;$PROJET&amp;quot; --network-enable-dry-run&lt;br /&gt;
   58  Application :&lt;br /&gt;
   59      ajlsm-deploy &amp;quot;$PROJET&amp;quot; --network-enable&lt;br /&gt;
   60  Avant activation, le programme effectue les contrôles prévus,&lt;br /&gt;
   61  notamment la recherche de conflits d&#039;adresses IPv4 par ARP.&lt;br /&gt;
   62  Après activation, vérifier :&lt;br /&gt;
   63  - Les adresses IPv4.&lt;br /&gt;
   64  - La route par défaut.&lt;br /&gt;
   65  - La passerelle.&lt;br /&gt;
   66  - Les DNS.&lt;br /&gt;
   67  - L&#039;adresse loopback, si elle est configurée.&lt;br /&gt;
   68  - Le paramètre onboot de la VM.&lt;br /&gt;
   69  Le mécanisme de repli en cas d&#039;échec réseau reste à valider&lt;br /&gt;
   70  par un test réel de panne.&lt;br /&gt;
   71  PHASE 8 - AUDIT SSH&lt;br /&gt;
   72      ajlsm-deploy &amp;quot;$PROJET&amp;quot; --ssh-audit&lt;br /&gt;
   73  Avant l&#039;audit SSH, le programme synchronise l&#039;identification&lt;br /&gt;
   74  du serveur dans /root/.ssh/known_hosts sur Saturne3.&lt;br /&gt;
   75  Il compare :&lt;br /&gt;
   76  - La clé publique ED25519 obtenue directement dans la VM&lt;br /&gt;
   77    via l&#039;agent QEMU.&lt;br /&gt;
   78  - La clé ED25519 présentée sur le réseau via ssh-keyscan.&lt;br /&gt;
   79  Si les clés diffèrent, l&#039;opération est refusée.&lt;br /&gt;
   80  Si elles correspondent, known_hosts peut être actualisé après&lt;br /&gt;
   81  sauvegarde.&lt;br /&gt;
   82  L&#039;audit ne modifie pas la configuration SSH de la VM.&lt;br /&gt;
   83  ATTENTION :&lt;br /&gt;
   84  Bien que l&#039;audit soit sans modification de la configuration SSH&lt;br /&gt;
   85  invitée, la synchronisation préalable peut modifier le fichier&lt;br /&gt;
   86  known_hosts de Saturne3.&lt;br /&gt;
   87  PHASE 9 - SECURISATION SSH&lt;br /&gt;
   88      ajlsm-deploy &amp;quot;$PROJET&amp;quot; --ssh-secure&lt;br /&gt;
   89  Cette phase désactive l&#039;authentification SSH par mot de passe&lt;br /&gt;
   90  et conserve l&#039;accès root par clé publique.&lt;br /&gt;
   91  Vérifier impérativement les accès par clé avant de confirmer.&lt;br /&gt;
   92  Après application, refaire un audit :&lt;br /&gt;
   93      ajlsm-deploy &amp;quot;$PROJET&amp;quot; --ssh-audit&lt;br /&gt;
   94  PHASE 10 - MOT DE PASSE DU COMPTE AJLSM&lt;br /&gt;
   95      ajlsm-deploy &amp;quot;$PROJET&amp;quot; --password-ajlsm&lt;br /&gt;
   96  Le mot de passe est demandé interactivement avec double saisie.&lt;br /&gt;
   97  Ne pas inscrire de mot de passe dans le YAML ou dans une commande.&lt;br /&gt;
   98  PHASE 11 - CERTIFICAT TLS INTERNE&lt;br /&gt;
   99      ajlsm-deploy &amp;quot;$PROJET&amp;quot; --tls-apply&lt;br /&gt;
  100  Initialisation ou vérification du certificat TLS interne.&lt;br /&gt;
  101  Vérifier le résultat et le fonctionnement du service concerné.&lt;br /&gt;
  102  6. VERIFICATIONS FINALES&lt;br /&gt;
  103  ------------------------&lt;br /&gt;
  104  Sur Saturne3, avec le VMID réellement attribué :&lt;br /&gt;
  105      qm status VMID&lt;br /&gt;
  106      qm config VMID&lt;br /&gt;
  107  Dans la VM :&lt;br /&gt;
  108      hostnamectl&lt;br /&gt;
  109      ip -br addr&lt;br /&gt;
  110      ip route&lt;br /&gt;
  111      resolvectl status&lt;br /&gt;
  112  Pour vérifier le volume racine :&lt;br /&gt;
  113      lsblk&lt;br /&gt;
  114      df -hT /&lt;br /&gt;
  115      pvs&lt;br /&gt;
  116      vgs&lt;br /&gt;
  117      lvs&lt;br /&gt;
  118  Pour vérifier SSH depuis Saturne3 :&lt;br /&gt;
  119      ssh root@ADRESSE_IP_VM&lt;br /&gt;
  120  Adapter VMID et ADRESSE_IP_VM au projet.&lt;br /&gt;
  121  Ne jamais accepter aveuglément une empreinte SSH différente.&lt;br /&gt;
  122  7. CONFIRMATIONS ET CODES DE RETOUR&lt;br /&gt;
  123  -----------------------------------&lt;br /&gt;
  124  Chaque modification nécessite une confirmation.&lt;br /&gt;
  125  La réponse par défaut est NON.&lt;br /&gt;
  126  Respecter la confirmation réellement demandée par la version&lt;br /&gt;
  127  installée du programme.&lt;br /&gt;
  128  Codes de retour :&lt;br /&gt;
  129      0 : succès&lt;br /&gt;
  130      1 : annulation&lt;br /&gt;
  131      2 : erreur&lt;br /&gt;
  132  Une erreur impose un diagnostic avant de poursuivre.&lt;br /&gt;
  133  8. REPRISE APRES INCIDENT&lt;br /&gt;
  134  -------------------------&lt;br /&gt;
  135  En cas d&#039;échec :&lt;br /&gt;
  136  1. Ne pas lancer la phase suivante.&lt;br /&gt;
  137  2. Conserver la sortie complète du programme.&lt;br /&gt;
  138  3. Vérifier le VMID et l&#039;identité de la VM.&lt;br /&gt;
  139  4. Contrôler son état dans Proxmox.&lt;br /&gt;
  140  5. Vérifier que le réseau est toujours isolé si nécessaire.&lt;br /&gt;
  141  6. Examiner les sauvegardes et informations de transaction.&lt;br /&gt;
  142  7. Corriger la cause avant de reprendre.&lt;br /&gt;
  143  Ne jamais supprimer une VM pour recommencer sans avoir vérifié&lt;br /&gt;
  144  son identité et ses données.&lt;br /&gt;
  145  Ne jamais modifier manuellement known_hosts pour contourner&lt;br /&gt;
  146  une erreur de correspondance de clés SSH.&lt;br /&gt;
  147  9. MAINTENANCE DES SCRIPTS&lt;br /&gt;
  148  --------------------------&lt;br /&gt;
  149  Vérifier la syntaxe Python :&lt;br /&gt;
  150      python3 -m py_compile \&lt;br /&gt;
  151          /usr/local/sbin/ajlsm-deploy \&lt;br /&gt;
  152          /usr/local/sbin/ajlsm_deploy_rootgrow.py \&lt;br /&gt;
  153          /usr/local/sbin/ajlsm_deploy_postconfig.py&lt;br /&gt;
  154  Les trois scripts forment un ensemble cohérent.&lt;br /&gt;
  155  Effectuer une sauvegarde avant toute modification.&lt;br /&gt;
  156  Ne pas restaurer un module isolément sans vérifier sa&lt;br /&gt;
  157  compatibilité avec les autres.&lt;br /&gt;
  158  10. ETAT DES VALIDATIONS AU 15 OCTOBRE 2026&lt;br /&gt;
  159  -------------------------------------------&lt;br /&gt;
  160  Recette MERCURE3 :&lt;br /&gt;
  161  - Clonage depuis TEMPLATE3.&lt;br /&gt;
  162  - Configuration des ressources.&lt;br /&gt;
  163  - Premier démarrage isolé.&lt;br /&gt;
  164  - Personnalisation système.&lt;br /&gt;
  165  - Configuration Netplan.&lt;br /&gt;
  166  - Contrôle ARP.&lt;br /&gt;
  167  - Activation réseau.&lt;br /&gt;
  168  - Vérifications réseau.&lt;br /&gt;
  169  Tests fonctionnels isolés du 15 octobre :&lt;br /&gt;
  170  - Validation de la comparaison des clés ED25519.&lt;br /&gt;
  171  - Acceptation de deux clés identiques.&lt;br /&gt;
  172  - Refus de clés différentes.&lt;br /&gt;
  173  - Refus de clés malformées.&lt;br /&gt;
  174  - Préservation de known_hosts en cas de refus.&lt;br /&gt;
  175  - Conservation des autres entrées de known_hosts.&lt;br /&gt;
  176  - Compilation Python des trois scripts.&lt;br /&gt;
  177  Restent à confirmer lors d&#039;un déploiement complet avec les&lt;br /&gt;
  178  dernières versions des scripts :&lt;br /&gt;
  179  - Extension du volume racine.&lt;br /&gt;
  180  - Enchaînement complet des phases.&lt;br /&gt;
  181  - Synchronisation SSH avec une nouvelle VM réelle.&lt;br /&gt;
  182  - Sécurisation SSH et postconfiguration.&lt;br /&gt;
  183  - Repli en cas d&#039;échec réseau.&lt;br /&gt;
  184  11. PRECAUTIONS&lt;br /&gt;
  185  ---------------&lt;br /&gt;
  186  TEMPLATE3 : VMID 506, modèle de clonage.&lt;br /&gt;
  187  MERCURE3 : VMID 505, VM utilisée pour la recette.&lt;br /&gt;
  188  Ces identifiants ne doivent jamais être réutilisés aveuglément.&lt;br /&gt;
  189  La VM 515 est indépendante de cette procédure et ne doit pas&lt;br /&gt;
  190  être modifiée.&lt;br /&gt;
  191  Le README applicatif présent sur TEMPLATE3 et MERCURE3 ne doit&lt;br /&gt;
  192  pas être remplacé par ce document.&lt;br /&gt;
  193  12. DOCUMENTATION COMPLEMENTAIRE&lt;br /&gt;
  194  --------------------------------&lt;br /&gt;
  195  Aide rapide :&lt;br /&gt;
  196      ajlsm-deploy --help&lt;br /&gt;
  197  Manuel système :&lt;br /&gt;
  198      man ajlsm-deploy&lt;br /&gt;
  199  Documentation technique complète :&lt;br /&gt;
  200      AJLSM-DEPLOY - Déploiement automatisé des VM Proxmox&lt;br /&gt;
  201      (documentation MediaWiki AJLSM)&lt;br /&gt;
  202  Le manuel et la documentation MediaWiki doivent être maintenus&lt;br /&gt;
  203  en cohérence avec les scripts.&lt;br /&gt;
  204  FIN DU README&lt;br /&gt;
  205  =============&lt;br /&gt;
  206  FIN_README&lt;br /&gt;
  207        chmod 644 /usr/local/sbin/README-ajlsm-deploy;     echo &amp;quot;README créé : /usr/local/sbin/README-ajlsm-deploy&amp;quot;; fi&lt;br /&gt;
  208  ls -l /usr/local/sbin/README-ajlsm-deploy&lt;br /&gt;
  209  head -20 /usr/local/sbin/README-ajlsm-deploy&lt;br /&gt;
  210  ls -l /usr/local/sbin/README-ajlsm-deploy&lt;br /&gt;
  211  head -20 /usr/local/sbin/README-ajlsm-deploy&lt;br /&gt;
  212  vim /usr/local/sbin/README-ajlsm-deploy&lt;br /&gt;
  213  man -w ajlsm-deploy&lt;br /&gt;
  214  cat /usr/local/man/man8/ajlsm-deploy.8&lt;br /&gt;
  215  python3 - &amp;lt;&amp;lt;&#039;PY&#039;&lt;br /&gt;
  216  from pathlib import Path&lt;br /&gt;
  217  from datetime import datetime&lt;br /&gt;
  218  import shutil&lt;br /&gt;
  219  path = Path(&amp;quot;/usr/local/man/man8/ajlsm-deploy.8&amp;quot;)&lt;br /&gt;
  220  original = path.read_text(encoding=&amp;quot;utf-8&amp;quot;)&lt;br /&gt;
  221  updated = original&lt;br /&gt;
  222  old_audit = r&amp;quot;&amp;quot;&amp;quot;.TP&lt;br /&gt;
  223  .B \-\-ssh-audit&lt;br /&gt;
  224  Contrôler en lecture seule les empreintes de clés autorisées, la configuration&lt;br /&gt;
  225  SSH, sudo et l&#039;accès par clé au compte ajlsm.&lt;br /&gt;
  226  &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  227  new_audit = r&amp;quot;&amp;quot;&amp;quot;.TP&lt;br /&gt;
  228  .B \-\-ssh-audit&lt;br /&gt;
  229  Identifier la VM Proxmox concernée, synchroniser sa clé d&#039;hôte SSH ED25519&lt;br /&gt;
  230  dans /root/.ssh/known_hosts sur Saturne3, puis contrôler les clés autorisées,&lt;br /&gt;
  231  la configuration SSH, sudo et l&#039;accès par clé au compte ajlsm.&lt;br /&gt;
  232  .PP&lt;br /&gt;
  233  Avant l&#039;audit, la clé publique ED25519 est récupérée directement dans&lt;br /&gt;
  234  l&#039;invité via l&#039;agent QEMU, puis comparée à la clé présentée sur le réseau&lt;br /&gt;
  235  par ssh-keyscan. La structure de la clé est vérifiée. Une clé malformée,&lt;br /&gt;
  236  une divergence ou une récupération impossible provoque un refus.&lt;br /&gt;
  237  .PP&lt;br /&gt;
  238  Lorsque les clés correspondent, le programme peut actualiser&lt;br /&gt;
  239  /root/.ssh/known_hosts après sauvegarde. Les anciennes entrées associées&lt;br /&gt;
  240  à l&#039;adresse IP, y compris les entrées hachées, sont supprimées de la copie&lt;br /&gt;
  241  de travail avant insertion de la clé vérifiée. Les autres entrées sont&lt;br /&gt;
  242  conservées. Le remplacement est atomique.&lt;br /&gt;
  243  .PP&lt;br /&gt;
  244  L&#039;audit de la configuration SSH dans l&#039;invité est en lecture seule,&lt;br /&gt;
  245  mais la synchronisation préalable peut modifier known_hosts sur Saturne3.&lt;br /&gt;
  246  &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  247  old_examples = r&amp;quot;&amp;quot;&amp;quot;\&amp;amp;./ajlsm-deploy projet-test.yaml --root-grow-apply&lt;br /&gt;
  248  \&amp;amp;./ajlsm-deploy projet-test.yaml --ssh-audit&lt;br /&gt;
  249  \&amp;amp;./ajlsm-deploy projet-test.yaml --ssh-secure&lt;br /&gt;
  250  \&amp;amp;./ajlsm-deploy projet-test.yaml --password-ajlsm&lt;br /&gt;
  251  \&amp;amp;./ajlsm-deploy projet-test.yaml --tls-apply&lt;br /&gt;
  252  \&amp;amp;./ajlsm-deploy projet-test.yaml --system-dry-run&lt;br /&gt;
  253  \&amp;amp;./ajlsm-deploy projet-test.yaml --system-apply&lt;br /&gt;
  254  \&amp;amp;./ajlsm-deploy projet-test.yaml --network-dry-run&lt;br /&gt;
  255  \&amp;amp;./ajlsm-deploy projet-test.yaml --network-apply&lt;br /&gt;
  256  \&amp;amp;./ajlsm-deploy projet-test.yaml --network-enable-dry-run&lt;br /&gt;
  257  \&amp;amp;./ajlsm-deploy projet-test.yaml --network-enable&lt;br /&gt;
  258  &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  259  new_examples = r&amp;quot;&amp;quot;&amp;quot;\&amp;amp;./ajlsm-deploy projet-test.yaml --root-grow-apply&lt;br /&gt;
  260  \&amp;amp;./ajlsm-deploy projet-test.yaml --system-dry-run&lt;br /&gt;
  261  \&amp;amp;./ajlsm-deploy projet-test.yaml --system-apply&lt;br /&gt;
  262  \&amp;amp;./ajlsm-deploy projet-test.yaml --network-dry-run&lt;br /&gt;
  263  \&amp;amp;./ajlsm-deploy projet-test.yaml --network-apply&lt;br /&gt;
  264  \&amp;amp;./ajlsm-deploy projet-test.yaml --network-enable-dry-run&lt;br /&gt;
  265  \&amp;amp;./ajlsm-deploy projet-test.yaml --network-enable&lt;br /&gt;
  266  \&amp;amp;./ajlsm-deploy projet-test.yaml --ssh-audit&lt;br /&gt;
  267  \&amp;amp;./ajlsm-deploy projet-test.yaml --ssh-secure&lt;br /&gt;
  268  \&amp;amp;./ajlsm-deploy projet-test.yaml --ssh-audit&lt;br /&gt;
  269  \&amp;amp;./ajlsm-deploy projet-test.yaml --password-ajlsm&lt;br /&gt;
  270  \&amp;amp;./ajlsm-deploy projet-test.yaml --tls-apply&lt;br /&gt;
  271  &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  272  old_limit = r&amp;quot;&amp;quot;&amp;quot;L&#039;absence de réponse ARP ne garantit pas qu&#039;une IP est libre, et ne&lt;br /&gt;
  273  remplace&lt;br /&gt;
  274  pas l&#039;inventaire réseau. Le repli réseau nécessite&lt;br /&gt;
  275  une recette sur une VM dédiée.&lt;br /&gt;
  276  &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  277  new_limit = r&amp;quot;&amp;quot;&amp;quot;L&#039;absence de réponse ARP ne garantit pas qu&#039;une IP est libre, et ne&lt;br /&gt;
  278  remplace&lt;br /&gt;
  279  pas l&#039;inventaire réseau. Le repli réseau nécessite&lt;br /&gt;
  280  une recette sur une VM dédiée.&lt;br /&gt;
  281  .PP&lt;br /&gt;
  282  La synchronisation des clés SSH a été validée par tests fonctionnels&lt;br /&gt;
  283  isolés le 15 octobre 2026 : clés concordantes, divergentes et malformées,&lt;br /&gt;
  284  préservation de known_hosts en cas de refus. Elle reste à confirmer&lt;br /&gt;
  285  lors d&#039;un nouveau déploiement complet sur une VM réelle.&lt;br /&gt;
  286  &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  287  replacements = [&lt;br /&gt;
  288      (&amp;quot;section SSH&amp;quot;, old_audit, new_audit),&lt;br /&gt;
  289      (&amp;quot;ordre des exemples&amp;quot;, old_examples, new_examples),&lt;br /&gt;
  290      (&amp;quot;limites et validation&amp;quot;, old_limit, new_limit),&lt;br /&gt;
  291  ]&lt;br /&gt;
  292  for label, old, new in replacements:&lt;br /&gt;
  293      count = updated.count(old)&lt;br /&gt;
  294      if count != 1:&lt;br /&gt;
  295          raise SystemExit(&lt;br /&gt;
  296              f&amp;quot;ERREUR : section &#039;{label}&#039; trouvée {count} fois. &amp;quot;&lt;br /&gt;
  297              &amp;quot;Aucune modification effectuée.&amp;quot;&lt;br /&gt;
  298          )&lt;br /&gt;
  299      updated = updated.replace(old, new, 1)&lt;br /&gt;
  300  backup = path.with_name(&lt;br /&gt;
  301      path.name + &amp;quot;.bak-&amp;quot; + datetime.now().strftime(&amp;quot;%Y%m%d-%H%M%S&amp;quot;)&lt;br /&gt;
  302  )&lt;br /&gt;
  303  shutil.copy2(path, backup)&lt;br /&gt;
  304  path.write_text(updated, encoding=&amp;quot;utf-8&amp;quot;)&lt;br /&gt;
  305  print(&amp;quot;Manuel actualisé :&amp;quot;, path)&lt;br /&gt;
  306  print(&amp;quot;Sauvegarde       :&amp;quot;, backup)&lt;br /&gt;
  307  print(&amp;quot;Sections modifiées : SSH, exemples, limites.&amp;quot;)&lt;br /&gt;
  308  PY&lt;br /&gt;
  309  man 8 ajlsm-deploy&lt;br /&gt;
  310  man 8 ajlsm-deploy | col -b | grep -n -E   &#039;known_hosts|ssh-keyscan|ED25519|déploiement complet&#039;&lt;br /&gt;
  311  mkdir -p /root/ajlsm-deploy-review/sauvegardes-man&lt;br /&gt;
  312  mv /usr/local/man/man8/ajlsm-deploy.8.bak-20261015-235157    /root/ajlsm-deploy-review/sauvegardes-man/&lt;br /&gt;
  313  man 8 ajlsm-deploy &amp;gt;/dev/null&lt;br /&gt;
  314  echo &amp;quot;=== INTERFACES RESEAU ===&amp;quot;&lt;br /&gt;
  315  ip -br -4 addr&lt;br /&gt;
  316  echo&lt;br /&gt;
  317  echo &amp;quot;=== ROUTE VERS EOLE3 ===&amp;quot;&lt;br /&gt;
  318  ip route get 192.168.123.202&lt;br /&gt;
  319  ip route get 51.178.110.230&lt;br /&gt;
  320  echo&lt;br /&gt;
  321  echo &amp;quot;=== MONTAGES NFS ===&amp;quot;&lt;br /&gt;
  322  findmnt -t nfs,nfs4 -o SOURCE,TARGET,FSTYPE,OPTIONS&lt;br /&gt;
  323  echo&lt;br /&gt;
  324  echo &amp;quot;=== CONNEXIONS ACTIVES VERS EOLE3 ===&amp;quot;&lt;br /&gt;
  325  ss -tn state established | grep -E   &#039;192\.168\.123\.202|51\.178\.110\.230&#039; || true&lt;br /&gt;
  326  echo&lt;br /&gt;
  327  echo &amp;quot;=== STOCKAGES PROXMOX ===&amp;quot;&lt;br /&gt;
  328  pvesm status&lt;br /&gt;
  329  echo &amp;quot;=== REFERENCES A EOLE3 DANS LES TACHES CRON ===&amp;quot;&lt;br /&gt;
  330  grep -RInE   &#039;eole3|51\.178\.110\.230|192\.168\.123\.202&#039;   /etc/cron.d /etc/crontab /var/spool/cron/crontabs   2&amp;gt;/dev/null || true&lt;br /&gt;
  331  echo&lt;br /&gt;
  332  echo &amp;quot;=== REFERENCES A EOLE3 DANS LES SCRIPTS LOCAUX ===&amp;quot;&lt;br /&gt;
  333  grep -RInE   &#039;eole3|51\.178\.110\.230|192\.168\.123\.202&#039;   /usr/local/sbin /usr/local/bin   2&amp;gt;/dev/null | head -60&lt;br /&gt;
  334  echo&lt;br /&gt;
  335  echo &amp;quot;=== TIMERS SYSTEMD ===&amp;quot;&lt;br /&gt;
  336  systemctl list-timers --all --no-pager&lt;br /&gt;
  337  exit&lt;br /&gt;
  338  qm status 505&lt;br /&gt;
  339  qm config 505&lt;br /&gt;
  340  qm set 505 --onboot 0&lt;br /&gt;
  341  qm shutdown 505 --timeout 120&lt;br /&gt;
  342  qm status 505&lt;br /&gt;
  343  PROJET_YAML=/etc/ajlsm/deploy/projets/mercure3.yaml&lt;br /&gt;
  344  ./ajlsm-deploy &amp;quot;$PROJET_YAML&amp;quot; --clone&lt;br /&gt;
  345  history&lt;br /&gt;
root@Saturne3:~# cd  /usr/local/sbin&lt;br /&gt;
root@Saturne3:/usr/local/sbin# ls -la&lt;br /&gt;
total 216&lt;br /&gt;
drwxr-xr-x  3 root root  4096 Oct 15 23:50 .&lt;br /&gt;
drwxr-xr-x 11 root root  4096 Mar 27  2026 ..&lt;br /&gt;
-rw-r--r--  1 root root 10453 Oct 15 23:44 README-ajlsm-deploy&lt;br /&gt;
drwxr-xr-x  2 root root  4096 Oct 15 23:26 __pycache__&lt;br /&gt;
-rwxr-x---  1 root root 66119 Oct 15 23:17 ajlsm-deploy&lt;br /&gt;
-rwxr-xr-x  1 root root 11954 Oct 15 21:41 ajlsm-deploy-check&lt;br /&gt;
-rwxr-xr-x  1 root root  6874 Oct 15 21:41 ajlsm-deploy-resources&lt;br /&gt;
-rwxr-xr-x  1 root root  2945 Oct 15 11:19 ajlsm-deploy.avant-clonage&lt;br /&gt;
-rwxr-xr-x  1 root root 10383 Oct 15 12:05 ajlsm-deploy.avant-first-boot&lt;br /&gt;
-rwxr-xr-x  1 root root  9664 Oct 15 11:51 ajlsm-deploy.avant-integration-ressources&lt;br /&gt;
-rwxr-x---  1 root root 18851 Oct 15 12:51 ajlsm-deploy.bak-20261015&lt;br /&gt;
-rw-r--r--  1 root root 10349 Oct 15 21:41 ajlsm_deploy_common.py&lt;br /&gt;
-rw-r--r--  1 root root  9595 Oct 15 23:26 ajlsm_deploy_postconfig.py&lt;br /&gt;
-rw-r--r--  1 root root  6192 Oct 15 22:14 ajlsm_deploy_rootgrow.py&lt;br /&gt;
-rwx------  1 root root   863 Apr 20 11:03 backup_pbs_saturne3.sh&lt;br /&gt;
-rwx------  1 root root  5289 Oct 14 12:55 supervision_rapport.sh&lt;br /&gt;
-rwxr-x---  1 root root  4112 Oct 14 12:23 supervision_updates.sh&lt;br /&gt;
-rw-r--r--  1 root root  1673 Oct 13 17:15 supervision_updates_collect.py&lt;br /&gt;
root@Saturne3:/usr/local/sbin# ./ajlsm-deploy &amp;quot;$PROJET_YAML&amp;quot; --clone&lt;br /&gt;
&lt;br /&gt;
=== PRÉCONTRÔLES ===&lt;br /&gt;
[OK] Configuration YAML chargée&lt;br /&gt;
&lt;br /&gt;
=== CONTRÔLES PROXMOX ===&lt;br /&gt;
[OK] VM source 506 présente&lt;br /&gt;
[OK] VM source 506 arrêtée&lt;br /&gt;
[OK] QEMU Guest Agent activé dans la configuration&lt;br /&gt;
[OK] Disque source scsi0 : 32 Gio&lt;br /&gt;
[OK] Prochain VMID proposé : 511 (non réservé)&lt;br /&gt;
[OK] CPU : 1 socket(s) × 8 cœur(s) = 8 vCPU&lt;br /&gt;
[OK] RAM : 16384 à 24576 Mio&lt;br /&gt;
[OK] Stockage local-zfs actif&lt;br /&gt;
[OK] Disque demandé : 100 Gio&lt;br /&gt;
[OK] Tags : interne&lt;br /&gt;
&lt;br /&gt;
=== CONTRÔLES RÉSEAU ===&lt;br /&gt;
[OK] Bridge vmbr2 présent&lt;br /&gt;
[OK] net0 / ens18 : 10.0.0.43/24&lt;br /&gt;
[OK] Bridge vmbr1 présent&lt;br /&gt;
[OK] net1 / ens19 : 192.168.123.27/24&lt;br /&gt;
[OK] IP loopback : 51.83.117.113/32&lt;br /&gt;
[OK] Passerelle : 10.0.0.4 via ens18&lt;br /&gt;
[OK] DNS : 10.0.0.4&lt;br /&gt;
[AVERTISSEMENT] Disponibilité réelle des IP non vérifiée sur le réseau&lt;br /&gt;
&lt;br /&gt;
=== BILAN ===&lt;br /&gt;
Erreurs : 0&lt;br /&gt;
Avertissements : 1&lt;br /&gt;
Précontrôles satisfaits. Aucune modification effectuée.&lt;br /&gt;
&lt;br /&gt;
Commande suggérée (à lancer manuellement) :&lt;br /&gt;
/usr/local/sbin/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --dry-run&lt;br /&gt;
&lt;br /&gt;
[ERREUR] Une VM nommée MERCURE3 existe déjà :&lt;br /&gt;
  VMID 505 : stopped&lt;br /&gt;
root@Saturne3:/usr/local/sbin# qm destroy 505&lt;br /&gt;
qm config 505&lt;br /&gt;
Configuration file &#039;nodes/Saturne3/qemu-server/505.conf&#039; does not exist&lt;br /&gt;
root@Saturne3:/usr/local/sbin# ./ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --clone&lt;br /&gt;
&lt;br /&gt;
=== PRÉCONTRÔLES ===&lt;br /&gt;
[OK] Configuration YAML chargée&lt;br /&gt;
&lt;br /&gt;
=== CONTRÔLES PROXMOX ===&lt;br /&gt;
[OK] VM source 506 présente&lt;br /&gt;
[OK] VM source 506 arrêtée&lt;br /&gt;
[OK] QEMU Guest Agent activé dans la configuration&lt;br /&gt;
[OK] Disque source scsi0 : 32 Gio&lt;br /&gt;
[OK] Prochain VMID proposé : 505 (non réservé)&lt;br /&gt;
[OK] CPU : 1 socket(s) × 8 cœur(s) = 8 vCPU&lt;br /&gt;
[OK] RAM : 16384 à 24576 Mio&lt;br /&gt;
[OK] Stockage local-zfs actif&lt;br /&gt;
[OK] Disque demandé : 100 Gio&lt;br /&gt;
[OK] Tags : interne&lt;br /&gt;
&lt;br /&gt;
=== CONTRÔLES RÉSEAU ===&lt;br /&gt;
[OK] Bridge vmbr2 présent&lt;br /&gt;
[OK] net0 / ens18 : 10.0.0.43/24&lt;br /&gt;
[OK] Bridge vmbr1 présent&lt;br /&gt;
[OK] net1 / ens19 : 192.168.123.27/24&lt;br /&gt;
[OK] IP loopback : 51.83.117.113/32&lt;br /&gt;
[OK] Passerelle : 10.0.0.4 via ens18&lt;br /&gt;
[OK] DNS : 10.0.0.4&lt;br /&gt;
[AVERTISSEMENT] Disponibilité réelle des IP non vérifiée sur le réseau&lt;br /&gt;
&lt;br /&gt;
=== BILAN ===&lt;br /&gt;
Erreurs : 0&lt;br /&gt;
Avertissements : 1&lt;br /&gt;
Précontrôles satisfaits. Aucune modification effectuée.&lt;br /&gt;
&lt;br /&gt;
Commande suggérée (à lancer manuellement) :&lt;br /&gt;
/usr/local/sbin/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --dry-run&lt;br /&gt;
&lt;br /&gt;
=== PLAN DE CLONAGE ===&lt;br /&gt;
Source   : VM 506&lt;br /&gt;
Clone    : MERCURE3&lt;br /&gt;
VMID     : 505&lt;br /&gt;
Stockage : local-zfs&lt;br /&gt;
Type     : clone complet&lt;br /&gt;
Réseau   : isolation avant premier démarrage&lt;br /&gt;
Onboot   : désactivé&lt;br /&gt;
Démarrage: aucun&lt;br /&gt;
&lt;br /&gt;
Pour créer la VM 505, confirmer (OUI/NON) : oui&lt;br /&gt;
&lt;br /&gt;
[ACTION] Clonage en cours...&lt;br /&gt;
[OK] VM 505 créée&lt;br /&gt;
[ACTION] Isolation de net0&lt;br /&gt;
[ACTION] Isolation de net1&lt;br /&gt;
[OK] Adresses MAC du clone distinctes de TEMPLATE3&lt;br /&gt;
[OK] Clone arrêté&lt;br /&gt;
[OK] Démarrage automatique désactivé&lt;br /&gt;
[OK] Toutes les interfaces réseau isolées&lt;br /&gt;
&lt;br /&gt;
=== CLONAGE TERMINÉ ===&lt;br /&gt;
VM 505 : MERCURE3&lt;br /&gt;
État : arrêtée, réseau isolé, onboot=0&lt;br /&gt;
Aucun démarrage effectué.&lt;br /&gt;
Prochaine phase : ressources CPU/RAM/disque.&lt;br /&gt;
&lt;br /&gt;
Commande suggérée (à lancer manuellement) :&lt;br /&gt;
/usr/local/sbin/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --resources-dry-run&lt;br /&gt;
root@Saturne3:/usr/local/sbin# /usr/local/sbin/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --resources-dry-run&lt;br /&gt;
&lt;br /&gt;
=== RESSOURCES : MERCURE3 (VM 505) ===&lt;br /&gt;
[OK] VM arrêtée, réseau isolé, onboot=0&lt;br /&gt;
[MODIFICATION] CPU : 2 x 4 -&amp;gt; 1 x 8&lt;br /&gt;
[MODIFICATION] RAM : 8192 -&amp;gt; 24576 Mio ; balloon : non défini -&amp;gt; 16384 Mio&lt;br /&gt;
[MODIFICATION] Disque scsi0 : 32 -&amp;gt; 100 Gio&lt;br /&gt;
&lt;br /&gt;
[DRY-RUN] Aucune modification effectuée.&lt;br /&gt;
&lt;br /&gt;
Commande suggérée (à lancer manuellement) :&lt;br /&gt;
/usr/local/sbin/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --configure-resources&lt;br /&gt;
root@Saturne3:/usr/local/sbin# /usr/local/sbin/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --configure-resources&lt;br /&gt;
&lt;br /&gt;
=== RESSOURCES : MERCURE3 (VM 505) ===&lt;br /&gt;
[OK] VM arrêtée, réseau isolé, onboot=0&lt;br /&gt;
[MODIFICATION] CPU : 2 x 4 -&amp;gt; 1 x 8&lt;br /&gt;
[MODIFICATION] RAM : 8192 -&amp;gt; 24576 Mio ; balloon : non défini -&amp;gt; 16384 Mio&lt;br /&gt;
[MODIFICATION] Disque scsi0 : 32 -&amp;gt; 100 Gio&lt;br /&gt;
&lt;br /&gt;
Pour appliquer les ressources à la VM 505, confirmer (OUI/NON) : oui&lt;br /&gt;
[ACTION] CPU : 2 x 4 -&amp;gt; 1 x 8&lt;br /&gt;
[ACTION] RAM : 8192 -&amp;gt; 24576 Mio ; balloon : non défini -&amp;gt; 16384 Mio&lt;br /&gt;
[ACTION] Disque scsi0 : 32 -&amp;gt; 100 Gio&lt;br /&gt;
&lt;br /&gt;
[OK] Ressources configurées et vérifiées.&lt;br /&gt;
[OK] VM toujours arrêtée et réseau isolé.&lt;br /&gt;
&lt;br /&gt;
Commande suggérée (à lancer manuellement) :&lt;br /&gt;
/usr/local/sbin/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --first-boot-dry-run&lt;br /&gt;
root@Saturne3:/usr/local/sbin# /usr/local/sbin/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --first-boot-apply&lt;br /&gt;
&lt;br /&gt;
=== PREMIER DÉMARRAGE : MERCURE3 (VM 505) ===&lt;br /&gt;
[OK] Démarrage automatique désactivé, interfaces isolées&lt;br /&gt;
État actuel : stopped&lt;br /&gt;
&lt;br /&gt;
Pour démarrer la VM 505 avec le réseau isolé, confirmer (OUI/NON) : oui&lt;br /&gt;
[ACTION] Démarrage de la VM 505 avec interfaces isolées&lt;br /&gt;
[OK] Agent QEMU disponible&lt;br /&gt;
[OK] ajlsm-clone-init terminé avec succès&lt;br /&gt;
[OK] UUID matériel conforme : ab93f3d0-c137-428c-acad-81f3196329c6&lt;br /&gt;
[OK] Phase de premier démarrage validée ; interfaces toujours isolées&lt;br /&gt;
&lt;br /&gt;
Commande suggérée (à lancer manuellement) :&lt;br /&gt;
/usr/local/sbin/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --system-dry-run&lt;br /&gt;
root@Saturne3:/usr/local/sbin# /usr/local/sbin/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --system-dry-run&lt;br /&gt;
[OK] Agent QEMU disponible&lt;br /&gt;
[OK] ajlsm-clone-init terminé avec succès&lt;br /&gt;
Cible : MERCURE3 VM505, UUID ab93f3d0-c137-428c-acad-81f3196329c6, hostname mercure3.ajlsm.com&lt;br /&gt;
État de reprise : nouvelle transaction&lt;br /&gt;
[DRY-RUN] Sauvegarder hostname, hosts et les deux machine-id dans l&#039;invité&lt;br /&gt;
[DRY-RUN] Préparer une identité aléatoire persistante, puis redémarrer isolé&lt;br /&gt;
[DRY-RUN] Vérifier boot_id, identité PID1, hostname, hosts et isolation&lt;br /&gt;
&lt;br /&gt;
Commande suggérée (à lancer manuellement) :&lt;br /&gt;
/usr/local/sbin/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --system-apply&lt;br /&gt;
root@Saturne3:/usr/local/sbin# /usr/local/sbin/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --system-apply&lt;br /&gt;
[OK] Agent QEMU disponible&lt;br /&gt;
[OK] ajlsm-clone-init terminé avec succès&lt;br /&gt;
Cible : MERCURE3 VM505, UUID ab93f3d0-c137-428c-acad-81f3196329c6, hostname mercure3.ajlsm.com&lt;br /&gt;
État de reprise : nouvelle transaction&lt;br /&gt;
&lt;br /&gt;
Cible : VM505 — mercure3.ajlsm.com&lt;br /&gt;
Cette opération modifiera l’identité système et redémarrera la VM avec le réseau isolé.&lt;br /&gt;
Confirmer (OUI/NON) : oui&lt;br /&gt;
[ACTION] Identité disque préparée ; identité active non encore validée&lt;br /&gt;
[OK] Agent QEMU disponible&lt;br /&gt;
[OK] ajlsm-clone-init terminé avec succès&lt;br /&gt;
[OK] Nouveau démarrage et identité active vérifiés ; VM505 toujours isolée&lt;br /&gt;
&lt;br /&gt;
Commande suggérée (à lancer manuellement) :&lt;br /&gt;
/usr/local/sbin/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --network-dry-run&lt;br /&gt;
root@Saturne3:/usr/local/sbin# /usr/local/sbin/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --network-dry&lt;br /&gt;
[OK] Agent QEMU disponible&lt;br /&gt;
[OK] ajlsm-clone-init terminé avec succès&lt;br /&gt;
Cible : MERCURE3 VM505 ; reseau Proxmox isole&lt;br /&gt;
  ens18: 10.0.0.43/24&lt;br /&gt;
  ens19: 192.168.123.27/24&lt;br /&gt;
  lo: 51.83.117.113/32 ; passerelle: 10.0.0.4 (ens18) ; DNS: 10.0.0.4&lt;br /&gt;
[DRY-RUN] Sauvegarder le Netplan initial, ecrire la configuration et executer netplan generate&lt;br /&gt;
[DRY-RUN] Aucune modification ni activation reseau&lt;br /&gt;
[OK] Déploiement terminé ; procéder aux vérifications finales du manuel.&lt;br /&gt;
root@Saturne3:/usr/local/sbin# /usr/local/sbin/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --network-apply&lt;br /&gt;
[OK] Agent QEMU disponible&lt;br /&gt;
[OK] ajlsm-clone-init terminé avec succès&lt;br /&gt;
Cible : MERCURE3 VM505 ; reseau Proxmox isole&lt;br /&gt;
  ens18: 10.0.0.43/24&lt;br /&gt;
  ens19: 192.168.123.27/24&lt;br /&gt;
  lo: 51.83.117.113/32 ; passerelle: 10.0.0.4 (ens18) ; DNS: 10.0.0.4&lt;br /&gt;
Cette operation remplace Netplan dans l&#039;invite, sans activer les interfaces Proxmox.&lt;br /&gt;
Confirmer (OUI/NON) : oui&lt;br /&gt;
[OK] Netplan ecrit et netplan generate valide : {&amp;quot;changed&amp;quot;: true, &amp;quot;backup&amp;quot;: true}&lt;br /&gt;
[OK] VM505 toujours isolee ; aucune activation des liens&lt;br /&gt;
&lt;br /&gt;
Commande suggérée (à lancer manuellement) :&lt;br /&gt;
/usr/local/sbin/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --network-enable-dry-run&lt;br /&gt;
root@Saturne3:/usr/local/sbin# /usr/local/sbin/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --network-enable&lt;br /&gt;
[OK] Agent QEMU disponible&lt;br /&gt;
[OK] ajlsm-clone-init terminé avec succès&lt;br /&gt;
[OK] ARP DAD 10.0.0.43 sur vmbr2 (aucune reponse)&lt;br /&gt;
[OK] ARP DAD 192.168.123.27 sur vmbr1 (aucune reponse)&lt;br /&gt;
[OK] VM505 UUID=ab93f3d0-c137-428c-acad-81f3196329c6, clone et Netplan valides, reseau isole&lt;br /&gt;
Activer le reseau de cette VM (OUI/NON) : oui&lt;br /&gt;
[OK] ARP DAD 10.0.0.43 sur vmbr2 (aucune reponse)&lt;br /&gt;
[OK] ARP DAD 192.168.123.27 sur vmbr1 (aucune reponse)&lt;br /&gt;
[OK] Adresses, loopback, route, DNS et ping passerelle valides&lt;br /&gt;
[OK] VM505 : reseau actif et controle, onboot conforme au YAML&lt;br /&gt;
&lt;br /&gt;
Commande suggérée (à lancer manuellement) :&lt;br /&gt;
/usr/local/sbin/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --ssh-audit&lt;br /&gt;
root@Saturne3:/usr/local/sbin# /usr/local/sbin/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --ssh-audit&lt;br /&gt;
[OK] Clé ED25519 vérifiée via QEMU : 10.0.0.43&lt;br /&gt;
[OK] known_hosts actualisé avec sauvegarde conservée&lt;br /&gt;
=== Contrôle SSH, sans modification ===&lt;br /&gt;
Identité : mercure3.ajlsm.com&lt;br /&gt;
&lt;br /&gt;
Clés autorisées ajlsm :&lt;br /&gt;
4096 SHA256:zGdW2VjyzL/p30BjtNy6dzXIahBWTH9djZLc62IKCAk siva@MacBook-Pro-de-Sivakavi.local (RSA)&lt;br /&gt;
256 SHA256:lVtwxE0No+RZNyOXpf64JBCnMYIk9YaMw43clCV92hk jlarvers@MacBook-Pro.lan (ED25519)&lt;br /&gt;
256 SHA256:HAHGVQ2Afy6vGJpLhJ2vftXonwV31QNOiFHH6t5BfB4 modou-mbp (ED25519)&lt;br /&gt;
&lt;br /&gt;
Configuration effective SSH :&lt;br /&gt;
permitrootlogin prohibit-password&lt;br /&gt;
pubkeyauthentication yes&lt;br /&gt;
passwordauthentication yes&lt;br /&gt;
kbdinteractiveauthentication no&lt;br /&gt;
&lt;br /&gt;
Règles sudo pour ajlsm :&lt;br /&gt;
User ajlsm may run the following commands on mercure3.ajlsm.com:&lt;br /&gt;
    (ALL : ALL) ALL&lt;br /&gt;
&lt;br /&gt;
Etat du mot de passe ajlsm :&lt;br /&gt;
ajlsm P 2026-05-22 0 99999 7 -1&lt;br /&gt;
[OK] Connexion ajlsm par clé vérifiée.&lt;br /&gt;
&lt;br /&gt;
Commande suggérée (à lancer manuellement) :&lt;br /&gt;
/usr/local/sbin/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --ssh-secure&lt;br /&gt;
root@Saturne3:/usr/local/sbin# /usr/local/sbin/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --ssh-secure&lt;br /&gt;
=== Contrôle SSH, sans modification ===&lt;br /&gt;
Identité : mercure3.ajlsm.com&lt;br /&gt;
&lt;br /&gt;
Clés autorisées ajlsm :&lt;br /&gt;
4096 SHA256:zGdW2VjyzL/p30BjtNy6dzXIahBWTH9djZLc62IKCAk siva@MacBook-Pro-de-Sivakavi.local (RSA)&lt;br /&gt;
256 SHA256:lVtwxE0No+RZNyOXpf64JBCnMYIk9YaMw43clCV92hk jlarvers@MacBook-Pro.lan (ED25519)&lt;br /&gt;
256 SHA256:HAHGVQ2Afy6vGJpLhJ2vftXonwV31QNOiFHH6t5BfB4 modou-mbp (ED25519)&lt;br /&gt;
&lt;br /&gt;
Configuration effective SSH :&lt;br /&gt;
permitrootlogin prohibit-password&lt;br /&gt;
pubkeyauthentication yes&lt;br /&gt;
passwordauthentication yes&lt;br /&gt;
kbdinteractiveauthentication no&lt;br /&gt;
&lt;br /&gt;
Règles sudo pour ajlsm :&lt;br /&gt;
User ajlsm may run the following commands on mercure3.ajlsm.com:&lt;br /&gt;
    (ALL : ALL) ALL&lt;br /&gt;
&lt;br /&gt;
Etat du mot de passe ajlsm :&lt;br /&gt;
ajlsm P 2026-05-22 0 99999 7 -1&lt;br /&gt;
[OK] Connexion ajlsm par clé vérifiée.&lt;br /&gt;
Appliquer PasswordAuthentication no et root par clé seulement [oui/non] : oui&lt;br /&gt;
[OK] SSH sécurisé ; root reste autorisé par clé.&lt;br /&gt;
[OK] Connexions root et ajlsm par clé toujours fonctionnelles.&lt;br /&gt;
&lt;br /&gt;
Commande suggérée (à lancer manuellement) :&lt;br /&gt;
/usr/local/sbin/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --password-ajlsm&lt;br /&gt;
root@Saturne3:/usr/local/sbin# /usr/local/sbin/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --password-ajlsm&lt;br /&gt;
Ouvrir passwd ajlsm sur MERCURE3 [oui/non] : oui&lt;br /&gt;
Le mot de passe sera demandé deux fois par passwd sur la VM.&lt;br /&gt;
Il ne sera pas enregistré dans le script. Le reporter manuellement dans le fichier ODS.&lt;br /&gt;
New password: &lt;br /&gt;
Retype new password: &lt;br /&gt;
passwd: password updated successfully&lt;br /&gt;
Connection to 10.0.0.43 closed.&lt;br /&gt;
[OK] Mot de passe ajlsm modifié ; vérifier ensuite sudo -i depuis ajlsm.&lt;br /&gt;
&lt;br /&gt;
Commande suggérée (à lancer manuellement) :&lt;br /&gt;
/usr/local/sbin/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --tls-apply&lt;br /&gt;
root@Saturne3:/usr/local/sbin# /usr/local/sbin/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --tls-apply&lt;br /&gt;
mercure3.ajlsm.com&lt;br /&gt;
subject=CN=clone-ab93f3d0-c13.internal&lt;br /&gt;
X509v3 Subject Alternative Name: &lt;br /&gt;
    DNS:clone-ab93f3d0-c13.internal&lt;br /&gt;
&lt;br /&gt;
Initialiser le certificat TLS interne [oui/non] : oui&lt;br /&gt;
Initialisation TLS pour : mercure3.ajlsm.com&lt;br /&gt;
....++++++++++++++++++++++++++++++++++++++++++*..+...++++++++++++++++++++++++++++++++++++++++++*........+............+...+.............+..+.......+.....................+..+............+.+.....+.+...+..+.+...+...........+.+...............+..............+.........+....+.....+.+.........+....................+...+..........+..............+.+.....+...+++++&lt;br /&gt;
...........+..+...+.............+.....+....+..+......+.........+......+.......++++++++++++++++++++++++++++++++++++++++++*.........++++++++++++++++++++++++++++++++++++++++++*....................+................+...+......+.....+....+.....+.........+...+....+...+..+..........+.........+.........+..+....+++++&lt;br /&gt;
-----&lt;br /&gt;
Syntax OK&lt;br /&gt;
&lt;br /&gt;
Initialisation TLS terminée.&lt;br /&gt;
Sauvegarde : /etc/ssl/ajlsm/backup.8vB54QHP&lt;br /&gt;
subject=CN=mercure3.ajlsm.com&lt;br /&gt;
notBefore=Oct 16 13:54:38 2026 GMT&lt;br /&gt;
notAfter=Oct 13 13:54:38 2036 GMT&lt;br /&gt;
subject=CN=mercure3.ajlsm.com&lt;br /&gt;
X509v3 Subject Alternative Name: &lt;br /&gt;
    DNS:mercure3.ajlsm.com&lt;br /&gt;
active&lt;br /&gt;
&lt;br /&gt;
[OK] Phases techniques terminées ; les opérations applicatives seront traitées séparément.&lt;br /&gt;
root@Saturne3:/usr/local/sbin# &lt;br /&gt;
root@Saturne3:/usr/local/sbin# &lt;br /&gt;
root@Saturne3:/usr/local/sbin# &lt;br /&gt;
root@Saturne3:/usr/local/sbin# &lt;br /&gt;
root@Saturne3:/usr/local/sbin# &lt;br /&gt;
root@Saturne3:/usr/local/sbin# &lt;br /&gt;
root@Saturne3:/usr/local/sbin# &lt;br /&gt;
root@Saturne3:/usr/local/sbin# &lt;br /&gt;
root@Saturne3:/usr/local/sbin# &lt;br /&gt;
root@Saturne3:/usr/local/sbin# ssh ajlsm@10.0.0.43&lt;br /&gt;
sudo -i&lt;br /&gt;
hostname&lt;br /&gt;
lsblk&lt;br /&gt;
df -hT /&lt;br /&gt;
Welcome to Ubuntu 26.04.1 LTS (GNU/Linux 7.0.0-38-generic x86_64)&lt;br /&gt;
&lt;br /&gt;
 * Documentation:  https://docs.ubuntu.com&lt;br /&gt;
 * Management:     https://landscape.canonical.com&lt;br /&gt;
 * Support:        https://ubuntu.com/pro&lt;br /&gt;
&lt;br /&gt;
 System information as of Fri Oct 16 03:56:00 PM CEST 2026&lt;br /&gt;
&lt;br /&gt;
  System load:  0.35               Processes:              190&lt;br /&gt;
  Usage of /:   54.2% of 14.66GB   Users logged in:        0&lt;br /&gt;
  Memory usage: 3%                 IPv4 address for ens18: 10.0.0.43&lt;br /&gt;
  Swap usage:   0%&lt;br /&gt;
&lt;br /&gt;
 * Canonical Workshop gives developers fast, composable, reproducible, and&lt;br /&gt;
   secure developer environments that are perfect for agentic workflows.&lt;br /&gt;
&lt;br /&gt;
   https://ubuntu.com/workshop&lt;br /&gt;
&lt;br /&gt;
Expanded Security Maintenance for Applications is not enabled.&lt;br /&gt;
&lt;br /&gt;
1 update can be applied immediately.&lt;br /&gt;
To see these additional updates run: apt list --upgradable&lt;br /&gt;
&lt;br /&gt;
9 additional security updates can be applied with ESM Apps.&lt;br /&gt;
Learn more about enabling ESM Apps service at https://ubuntu.com/esm&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You have new mail.&lt;br /&gt;
Last login: Thu Oct 15 08:18:27 2026 from 10.40.0.2&lt;br /&gt;
ajlsm@mercure3:~$ sudo -i&lt;br /&gt;
[sudo: authenticate] Password:                     &lt;br /&gt;
root@mercure3:~# hostname&lt;br /&gt;
lsblk&lt;br /&gt;
df -hT /&lt;br /&gt;
mercure3.ajlsm.com&lt;br /&gt;
NAME                      MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS&lt;br /&gt;
sda                         8:0    0  100G  0 disk &lt;br /&gt;
├─sda1                      8:1    0    1M  0 part &lt;br /&gt;
├─sda2                      8:2    0    2G  0 part /boot&lt;br /&gt;
└─sda3                      8:3    0   30G  0 part &lt;br /&gt;
  └─ubuntu--vg-ubuntu--lv 252:0    0   15G  0 lvm  /&lt;br /&gt;
Filesystem                        Type  Size  Used Avail Use% Mounted on&lt;br /&gt;
/dev/mapper/ubuntu--vg-ubuntu--lv ext4   15G  8.0G  6.0G  58% /&lt;br /&gt;
root@mercure3:~# pvs&lt;br /&gt;
vgs&lt;br /&gt;
lvs -o lv_path,lv_size,vg_name&lt;br /&gt;
findmnt -no SOURCE,FSTYPE /&lt;br /&gt;
command -v growpart&lt;br /&gt;
  PV         VG        Fmt  Attr PSize   PFree &lt;br /&gt;
  /dev/sda3  ubuntu-vg lvm2 a--  &amp;lt;30.00g 15.00g&lt;br /&gt;
  VG        #PV #LV #SN Attr   VSize   VFree &lt;br /&gt;
  ubuntu-vg   1   1   0 wz--n- &amp;lt;30.00g 15.00g&lt;br /&gt;
  Path                     LSize   VG       &lt;br /&gt;
  /dev/ubuntu-vg/ubuntu-lv &amp;lt;15.00g ubuntu-vg&lt;br /&gt;
/dev/mapper/ubuntu--vg-ubuntu--lv ext4&lt;br /&gt;
/usr/bin/growpart&lt;br /&gt;
root@mercure3:~# &lt;br /&gt;
root@mercure3:~# lsblk&lt;br /&gt;
pvs&lt;br /&gt;
vgs&lt;br /&gt;
df -hT /&lt;br /&gt;
NAME                      MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS&lt;br /&gt;
sda                         8:0    0  100G  0 disk &lt;br /&gt;
├─sda1                      8:1    0    1M  0 part &lt;br /&gt;
├─sda2                      8:2    0    2G  0 part /boot&lt;br /&gt;
└─sda3                      8:3    0   30G  0 part &lt;br /&gt;
  └─ubuntu--vg-ubuntu--lv 252:0    0   15G  0 lvm  /&lt;br /&gt;
  PV         VG        Fmt  Attr PSize   PFree &lt;br /&gt;
  /dev/sda3  ubuntu-vg lvm2 a--  &amp;lt;30.00g 15.00g&lt;br /&gt;
  VG        #PV #LV #SN Attr   VSize   VFree &lt;br /&gt;
  ubuntu-vg   1   1   0 wz--n- &amp;lt;30.00g 15.00g&lt;br /&gt;
Filesystem                        Type  Size  Used Avail Use% Mounted on&lt;br /&gt;
/dev/mapper/ubuntu--vg-ubuntu--lv ext4   15G  8.0G  6.0G  58% /&lt;br /&gt;
root@mercure3:~# growpart /dev/sda 3&lt;br /&gt;
CHANGED: partition=3 start=4198400 old: size=62908416 end=67106815 new: size=205516767 end=209715166&lt;br /&gt;
root@mercure3:~# /usr/local/sbin/ajlsm-deploy --help&lt;br /&gt;
-bash: /usr/local/sbin/ajlsm-deploy: No such file or directory&lt;br /&gt;
root@mercure3:~# exit&lt;br /&gt;
logout&lt;br /&gt;
ajlsm@mercure3:~$ exit&lt;br /&gt;
logout&lt;br /&gt;
Connection to 10.0.0.43 closed.&lt;br /&gt;
root@Saturne3:~# /usr/local/sbin/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --root-grow-apply&lt;br /&gt;
=== EXTENSION RACINE : VM 505 (APPLY) ===&lt;br /&gt;
Étendre la partition, le LVM et ext4 de la VM 505 [OUI/NON] : oui&lt;br /&gt;
[ETAT] {&amp;quot;disk_bytes&amp;quot;: 107374182400, &amp;quot;grow_partition&amp;quot;: false, &amp;quot;lv&amp;quot;: &amp;quot;/dev/ubuntu-vg/ubuntu-lv&amp;quot;, &amp;quot;partition_free_bytes_approx&amp;quot;: 16896, &amp;quot;pv&amp;quot;: &amp;quot;/dev/sda3&amp;quot;, &amp;quot;root&amp;quot;: &amp;quot;/dev/mapper/ubuntu--vg-ubuntu--lv ext4&amp;quot;, &amp;quot;vg&amp;quot;: &amp;quot;ubuntu-vg&amp;quot;, &amp;quot;vg_free_bytes&amp;quot;: 89120571392}&lt;br /&gt;
[ACTION] pvresize /dev/sda3&lt;br /&gt;
[ACTION] lvextend -r -l +100%FREE /dev/ubuntu-vg/ubuntu-lv&lt;br /&gt;
[OK] Extension racine vérifiée : Filesystem                        Type  Size  Used Avail Use% Mounted on&lt;br /&gt;
/dev/mapper/ubuntu--vg-ubuntu--lv ext4   97G  8.0G   85G   9% /&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Commande suggérée (à lancer manuellement) :&lt;br /&gt;
/usr/local/sbin/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --system-apply&lt;br /&gt;
[OK] Déploiement terminé ; procéder aux vérifications finales du manuel.&lt;br /&gt;
root@Saturne3:~# Read from remote host 141.95.206.118: Connection reset by peer&lt;br /&gt;
Connection to 141.95.206.118 closed.&lt;br /&gt;
client_loop: send disconnect: Broken pipe&lt;br /&gt;
jlarvers@MacBook-Pro ~ % ssh saturne3&lt;br /&gt;
Linux Saturne3 7.0.14-23-pve #1 SMP PREEMPT_DYNAMIC PMX 7.0.14-23 (2026-10-07T20:25Z) x86_64&lt;br /&gt;
&lt;br /&gt;
The programs included with the Debian GNU/Linux system are free software;&lt;br /&gt;
the exact distribution terms for each program are described in the&lt;br /&gt;
individual files in /usr/share/doc/*/copyright.&lt;br /&gt;
&lt;br /&gt;
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent&lt;br /&gt;
permitted by applicable law.&lt;br /&gt;
Last login: Fri Oct 16 16:02:53 2026 from 109.190.129.96&lt;br /&gt;
root@Saturne3:~# ls -la&lt;br /&gt;
total 208&lt;br /&gt;
drwx------  9 root root  4096 Oct 16 16:44  .&lt;br /&gt;
drwxr-xr-x 18 root root  4096 Apr  1  2026  ..&lt;br /&gt;
-rw-------  1 root root 14581 Oct 16 16:36  .bash_history&lt;br /&gt;
-rw-r--r--  1 root root   607 Mar  2  2026  .bashrc&lt;br /&gt;
drwxr-xr-x  3 root root  4096 Apr  2  2026  .cache&lt;br /&gt;
drwx------  5 root root  4096 Apr 20 10:28  .config&lt;br /&gt;
-rw-r--r--  1 root root    35 Apr 30 11:01  .forward&lt;br /&gt;
-rw-------  1 root root    28 Oct 15 23:52  .lesshst&lt;br /&gt;
drwxr-xr-x  3 root root  4096 Apr  1  2026  .local&lt;br /&gt;
-rw-r--r--  1 root root    50 Apr  1  2026  .ovhrc&lt;br /&gt;
-rw-------  1 root root    37 Apr 20 11:05  .pbs_token_saturne3&lt;br /&gt;
-rw-r--r--  1 root root   132 Mar  2  2026  .profile&lt;br /&gt;
-rw-------  1 root root  1024 Apr  1  2026  .rnd&lt;br /&gt;
-rw-r--r--  1 root root    75 Apr 20 10:24  .selected_editor&lt;br /&gt;
drwx------  2 root root  4096 Oct 16 15:53  .ssh&lt;br /&gt;
-rw-------  1 root root 16696 Oct 15 23:50  .viminfo&lt;br /&gt;
-rw-r--r--  1 root root 32718 Oct 16 16:06  ajlsm-deploy-actuel.tar.gz&lt;br /&gt;
-rw-r--r--  1 root root 46186 Oct 16 16:44  ajlsm-deploy-cycle.zip&lt;br /&gt;
drwxr-x---  8 root root  4096 Oct 15 23:53  ajlsm-deploy-review&lt;br /&gt;
-rw-------  1 root root   161 Apr  2  2026  dead.letter&lt;br /&gt;
drwxr-xr-x  6 root root  4096 Oct 14 13:16  export-supervision-svn&lt;br /&gt;
-rw-r--r--  1 root root 12216 Oct 15 23:52 &#039;m-deploy | col -b | grep -n -E &#039;&lt;br /&gt;
-rw-r--r--  1 root root  4680 Oct 14 13:19  supervision-ajlsm-2026-10-14.tar.gz&lt;br /&gt;
drwxr-xr-x  2 root root  4096 Oct 13 17:15  supervision-test&lt;br /&gt;
root@Saturne3:~# mkdir -p /root/ajlsm-deploy/archives&lt;br /&gt;
mkdir -p /root/ajlsm-deploy/recettes/20261016&lt;br /&gt;
&lt;br /&gt;
mv /root/ajlsm-deploy-actuel.tar.gz /root/ajlsm-deploy/archives/&lt;br /&gt;
mv /root/ajlsm-deploy-cycle.zip /root/ajlsm-deploy/archives/&lt;br /&gt;
&lt;br /&gt;
unzip /root/ajlsm-deploy/archives/ajlsm-deploy-cycle.zip \&lt;br /&gt;
  -d /root/ajlsm-deploy/recettes/20261016&lt;br /&gt;
&lt;br /&gt;
cd /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle&lt;br /&gt;
chmod 750 ajlsm-deploy ajlsm-deploy-check ajlsm-deploy-resources ajlsm-deploy-cycle&lt;br /&gt;
-bash: unzip: command not found&lt;br /&gt;
-bash: cd: /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle: No such file or directory&lt;br /&gt;
chmod: cannot access &#039;ajlsm-deploy-check&#039;: No such file or directory&lt;br /&gt;
chmod: cannot access &#039;ajlsm-deploy-resources&#039;: No such file or directory&lt;br /&gt;
chmod: cannot access &#039;ajlsm-deploy-cycle&#039;: No such file or directory&lt;br /&gt;
root@Saturne3:~# mkdir -p /root/ajlsm-deploy/archives&lt;br /&gt;
mkdir -p /root/ajlsm-deploy/recettes/20261016&lt;br /&gt;
&lt;br /&gt;
mv /root/ajlsm-deploy-actuel.tar.gz /root/ajlsm-deploy/archives/&lt;br /&gt;
mv /root/ajlsm-deploy-cycle.zip /root/ajlsm-deploy/archives/&lt;br /&gt;
&lt;br /&gt;
unzip /root/ajlsm-deploy/archives/ajlsm-deploy-cycle.zip \&lt;br /&gt;
  -d /root/ajlsm-deploy/recettes/20261016&lt;br /&gt;
&lt;br /&gt;
cd /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle&lt;br /&gt;
chmod 750 ajlsm-deploy ajlsm-deploy-check ajlsm-deploy-resources ajlsm-deploy-cycle&lt;br /&gt;
mv: cannot stat &#039;/root/ajlsm-deploy-actuel.tar.gz&#039;: No such file or directory&lt;br /&gt;
mv: cannot stat &#039;/root/ajlsm-deploy-cycle.zip&#039;: No such file or directory&lt;br /&gt;
-bash: unzip: command not found&lt;br /&gt;
-bash: cd: /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle: No such file or directory&lt;br /&gt;
chmod: cannot access &#039;ajlsm-deploy-check&#039;: No such file or directory&lt;br /&gt;
chmod: cannot access &#039;ajlsm-deploy-resources&#039;: No such file or directory&lt;br /&gt;
chmod: cannot access &#039;ajlsm-deploy-cycle&#039;: No such file or directory&lt;br /&gt;
root@Saturne3:~# python3 -m zipfile -e \&lt;br /&gt;
  /root/ajlsm-deploy/archives/ajlsm-deploy-cycle.zip \&lt;br /&gt;
  /root/ajlsm-deploy/recettes/20261016 &amp;amp;&amp;amp;&lt;br /&gt;
cd /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle &amp;amp;&amp;amp;&lt;br /&gt;
chmod 750 ajlsm-deploy ajlsm-deploy-check ajlsm-deploy-resources ajlsm-deploy-cycle &amp;amp;&amp;amp;&lt;br /&gt;
./ajlsm-deploy-cycle /etc/ajlsm/deploy/projets/mercure3.yaml --plan&lt;br /&gt;
&lt;br /&gt;
=== ÉTAPE 1/11 : clonage ===&lt;br /&gt;
/usr/bin/python3 /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --clone --agent-timeout 300&lt;br /&gt;
&lt;br /&gt;
=== ÉTAPE 2/11 : ressources ===&lt;br /&gt;
/usr/bin/python3 /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --configure-resources --agent-timeout 300&lt;br /&gt;
&lt;br /&gt;
=== ÉTAPE 3/11 : premier-demarrage ===&lt;br /&gt;
/usr/bin/python3 /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --first-boot-apply --agent-timeout 300&lt;br /&gt;
&lt;br /&gt;
=== ÉTAPE 4/11 : extension-racine ===&lt;br /&gt;
/usr/bin/python3 /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --root-grow-apply --agent-timeout 300&lt;br /&gt;
&lt;br /&gt;
=== ÉTAPE 5/11 : identite ===&lt;br /&gt;
/usr/bin/python3 /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --system-apply --agent-timeout 300&lt;br /&gt;
&lt;br /&gt;
=== ÉTAPE 6/11 : netplan ===&lt;br /&gt;
/usr/bin/python3 /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --network-apply --agent-timeout 300&lt;br /&gt;
&lt;br /&gt;
=== ÉTAPE 7/11 : activation-reseau ===&lt;br /&gt;
/usr/bin/python3 /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --network-enable --agent-timeout 300&lt;br /&gt;
&lt;br /&gt;
=== ÉTAPE 8/11 : audit-ssh ===&lt;br /&gt;
/usr/bin/python3 /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --ssh-audit --agent-timeout 300&lt;br /&gt;
&lt;br /&gt;
=== ÉTAPE 9/11 : securisation-ssh ===&lt;br /&gt;
/usr/bin/python3 /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --ssh-secure --agent-timeout 300&lt;br /&gt;
&lt;br /&gt;
=== ÉTAPE 10/11 : mot-de-passe ===&lt;br /&gt;
/usr/bin/python3 /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --password-ajlsm --agent-timeout 300&lt;br /&gt;
&lt;br /&gt;
=== ÉTAPE 11/11 : tls ===&lt;br /&gt;
/usr/bin/python3 /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --tls-apply --agent-timeout 300&lt;br /&gt;
&lt;br /&gt;
[PLAN] Aucune phase exécutée.&lt;br /&gt;
root@Saturne3:~/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle# &lt;br /&gt;
root@Saturne3:~/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle# &lt;br /&gt;
root@Saturne3:~/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle# qm config 505&lt;br /&gt;
agent: 1&lt;br /&gt;
balloon: 16384&lt;br /&gt;
boot: order=scsi0;net0&lt;br /&gt;
cores: 8&lt;br /&gt;
cpu: x86-64-v2-AES&lt;br /&gt;
memory: 24576&lt;br /&gt;
meta: creation-qemu=11.0.0,ctime=1779439732&lt;br /&gt;
name: MERCURE3&lt;br /&gt;
net0: virtio=BC:24:11:F6:BC:A4,bridge=vmbr2,firewall=1,link_down=0&lt;br /&gt;
net1: virtio=BC:24:11:A5:17:8E,bridge=vmbr1,firewall=1,link_down=0&lt;br /&gt;
numa: 0&lt;br /&gt;
onboot: 1&lt;br /&gt;
ostype: l26&lt;br /&gt;
scsi0: local-zfs:vm-505-disk-0,iothread=1,size=100G&lt;br /&gt;
scsihw: virtio-scsi-single&lt;br /&gt;
smbios1: uuid=ab93f3d0-c137-428c-acad-81f3196329c6&lt;br /&gt;
sockets: 1&lt;br /&gt;
tags: interne&lt;br /&gt;
vmgenid: d71326df-130f-4394-bd68-6f8c493047e1&lt;br /&gt;
root@Saturne3:~/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle# qm set 505 --onboot 0 &amp;amp;&amp;amp;&lt;br /&gt;
qm shutdown 505 --timeout 120 &amp;amp;&amp;amp;&lt;br /&gt;
qm destroy 505 &amp;amp;&amp;amp;&lt;br /&gt;
./ajlsm-deploy-cycle /etc/ajlsm/deploy/projets/mercure3.yaml&lt;br /&gt;
update VM 505: -onboot 0&lt;br /&gt;
&lt;br /&gt;
=== ÉTAPE 1/11 : clonage ===&lt;br /&gt;
/usr/bin/python3 /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --clone --agent-timeout 300&lt;br /&gt;
&lt;br /&gt;
=== PRÉCONTRÔLES ===&lt;br /&gt;
[OK] Configuration YAML chargée&lt;br /&gt;
&lt;br /&gt;
=== CONTRÔLES PROXMOX ===&lt;br /&gt;
[OK] VM source 506 présente&lt;br /&gt;
[OK] VM source 506 arrêtée&lt;br /&gt;
[OK] QEMU Guest Agent activé dans la configuration&lt;br /&gt;
[OK] Disque source scsi0 : 32 Gio&lt;br /&gt;
[OK] Prochain VMID proposé : 505 (non réservé)&lt;br /&gt;
[OK] CPU : 1 socket(s) × 8 cœur(s) = 8 vCPU&lt;br /&gt;
[OK] RAM : 16384 à 24576 Mio&lt;br /&gt;
[OK] Stockage local-zfs actif&lt;br /&gt;
[OK] Disque demandé : 100 Gio&lt;br /&gt;
[OK] Tags : interne&lt;br /&gt;
&lt;br /&gt;
=== CONTRÔLES RÉSEAU ===&lt;br /&gt;
[OK] Bridge vmbr2 présent&lt;br /&gt;
[OK] net0 / ens18 : 10.0.0.43/24&lt;br /&gt;
[OK] Bridge vmbr1 présent&lt;br /&gt;
[OK] net1 / ens19 : 192.168.123.27/24&lt;br /&gt;
[OK] IP loopback : 51.83.117.113/32&lt;br /&gt;
[OK] Passerelle : 10.0.0.4 via ens18&lt;br /&gt;
[OK] DNS : 10.0.0.4&lt;br /&gt;
[AVERTISSEMENT] Disponibilité réelle des IP non vérifiée sur le réseau&lt;br /&gt;
&lt;br /&gt;
=== BILAN ===&lt;br /&gt;
Erreurs : 0&lt;br /&gt;
Avertissements : 1&lt;br /&gt;
Précontrôles satisfaits. Aucune modification effectuée.&lt;br /&gt;
&lt;br /&gt;
=== PLAN DE CLONAGE ===&lt;br /&gt;
Source   : VM 506&lt;br /&gt;
Clone    : MERCURE3&lt;br /&gt;
VMID     : 505&lt;br /&gt;
Stockage : local-zfs&lt;br /&gt;
Type     : clone complet&lt;br /&gt;
Réseau   : isolation avant premier démarrage&lt;br /&gt;
Onboot   : désactivé&lt;br /&gt;
Démarrage: aucun&lt;br /&gt;
&lt;br /&gt;
Pour créer la VM 505, confirmer (OUI/NON) : oui&lt;br /&gt;
&lt;br /&gt;
[ACTION] Clonage en cours...&lt;br /&gt;
[OK] VM 505 créée&lt;br /&gt;
[ACTION] Isolation de net0&lt;br /&gt;
[ACTION] Isolation de net1&lt;br /&gt;
[OK] Adresses MAC du clone distinctes de TEMPLATE3&lt;br /&gt;
[OK] Clone arrêté&lt;br /&gt;
[OK] Démarrage automatique désactivé&lt;br /&gt;
[OK] Toutes les interfaces réseau isolées&lt;br /&gt;
&lt;br /&gt;
=== CLONAGE TERMINÉ ===&lt;br /&gt;
VM 505 : MERCURE3&lt;br /&gt;
État : arrêtée, réseau isolé, onboot=0&lt;br /&gt;
Aucun démarrage effectué.&lt;br /&gt;
Prochaine phase : ressources CPU/RAM/disque.&lt;br /&gt;
&lt;br /&gt;
=== ÉTAPE 2/11 : ressources ===&lt;br /&gt;
/usr/bin/python3 /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --configure-resources --agent-timeout 300&lt;br /&gt;
&lt;br /&gt;
=== RESSOURCES : MERCURE3 (VM 505) ===&lt;br /&gt;
[OK] VM arrêtée, réseau isolé, onboot=0&lt;br /&gt;
[MODIFICATION] CPU : 2 x 4 -&amp;gt; 1 x 8&lt;br /&gt;
[MODIFICATION] RAM : 8192 -&amp;gt; 24576 Mio ; balloon : non défini -&amp;gt; 16384 Mio&lt;br /&gt;
[MODIFICATION] Disque scsi0 : 32 -&amp;gt; 100 Gio&lt;br /&gt;
&lt;br /&gt;
Pour appliquer les ressources à la VM 505, confirmer (OUI/NON) : oui&lt;br /&gt;
[ACTION] CPU : 2 x 4 -&amp;gt; 1 x 8&lt;br /&gt;
[ACTION] RAM : 8192 -&amp;gt; 24576 Mio ; balloon : non défini -&amp;gt; 16384 Mio&lt;br /&gt;
[ACTION] Disque scsi0 : 32 -&amp;gt; 100 Gio&lt;br /&gt;
&lt;br /&gt;
[OK] Ressources configurées et vérifiées.&lt;br /&gt;
[OK] VM toujours arrêtée et réseau isolé.&lt;br /&gt;
&lt;br /&gt;
=== ÉTAPE 3/11 : premier-demarrage ===&lt;br /&gt;
/usr/bin/python3 /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --first-boot-apply --agent-timeout 300&lt;br /&gt;
&lt;br /&gt;
=== PREMIER DÉMARRAGE : MERCURE3 (VM 505) ===&lt;br /&gt;
[OK] Démarrage automatique désactivé, interfaces isolées&lt;br /&gt;
État actuel : stopped&lt;br /&gt;
&lt;br /&gt;
Pour démarrer la VM 505 avec le réseau isolé, confirmer (OUI/NON) : oui&lt;br /&gt;
[ACTION] Démarrage de la VM 505 avec interfaces isolées&lt;br /&gt;
[OK] Agent QEMU disponible&lt;br /&gt;
[OK] ajlsm-clone-init terminé avec succès&lt;br /&gt;
[OK] UUID matériel conforme : 89aea8cb-9fd5-4b3b-9e06-a80cfa014f5b&lt;br /&gt;
[OK] Phase de premier démarrage validée ; interfaces toujours isolées&lt;br /&gt;
&lt;br /&gt;
=== ÉTAPE 4/11 : extension-racine ===&lt;br /&gt;
/usr/bin/python3 /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --root-grow-apply --agent-timeout 300&lt;br /&gt;
=== EXTENSION RACINE : VM 505 (APPLY) ===&lt;br /&gt;
Étendre la partition, le LVM et ext4 de la VM 505 [OUI/NON] : oui&lt;br /&gt;
[ETAT] {&amp;quot;disk_bytes&amp;quot;: 107374182400, &amp;quot;grow_partition&amp;quot;: true, &amp;quot;lv&amp;quot;: &amp;quot;/dev/ubuntu-vg/ubuntu-lv&amp;quot;, &amp;quot;partition_free_bytes_approx&amp;quot;: 73015492608, &amp;quot;pv&amp;quot;: &amp;quot;/dev/sda3&amp;quot;, &amp;quot;root&amp;quot;: &amp;quot;/dev/mapper/ubuntu--vg-ubuntu--lv ext4&amp;quot;, &amp;quot;vg&amp;quot;: &amp;quot;ubuntu-vg&amp;quot;, &amp;quot;vg_free_bytes&amp;quot;: 16106127360}&lt;br /&gt;
[ACTION] growpart /dev/sda 3&lt;br /&gt;
[ACTION] pvresize /dev/sda3&lt;br /&gt;
[ACTION] lvextend -r -l +100%FREE /dev/ubuntu-vg/ubuntu-lv&lt;br /&gt;
[OK] Extension racine vérifiée : Filesystem                        Type  Size  Used Avail Use% Mounted on&lt;br /&gt;
/dev/mapper/ubuntu--vg-ubuntu--lv ext4   97G  8.0G   85G   9% /&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ÉTAPE 5/11 : identite ===&lt;br /&gt;
/usr/bin/python3 /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --system-apply --agent-timeout 300&lt;br /&gt;
[OK] Agent QEMU disponible&lt;br /&gt;
[OK] ajlsm-clone-init terminé avec succès&lt;br /&gt;
Cible : MERCURE3 VM505, UUID 89aea8cb-9fd5-4b3b-9e06-a80cfa014f5b, hostname mercure3.ajlsm.com&lt;br /&gt;
État de reprise : nouvelle transaction&lt;br /&gt;
&lt;br /&gt;
Cible : VM505 — mercure3.ajlsm.com&lt;br /&gt;
Cette opération modifiera l’identité système et redémarrera la VM avec le réseau isolé.&lt;br /&gt;
Confirmer (OUI/NON) : oui&lt;br /&gt;
[ACTION] Identité disque préparée ; identité active non encore validée&lt;br /&gt;
[OK] Agent QEMU disponible&lt;br /&gt;
[OK] ajlsm-clone-init terminé avec succès&lt;br /&gt;
[OK] Nouveau démarrage et identité active vérifiés ; VM505 toujours isolée&lt;br /&gt;
&lt;br /&gt;
=== ÉTAPE 6/11 : netplan ===&lt;br /&gt;
/usr/bin/python3 /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --network-apply --agent-timeout 300&lt;br /&gt;
[OK] Agent QEMU disponible&lt;br /&gt;
[OK] ajlsm-clone-init terminé avec succès&lt;br /&gt;
Cible : MERCURE3 VM505 ; reseau Proxmox isole&lt;br /&gt;
  ens18: 10.0.0.43/24&lt;br /&gt;
  ens19: 192.168.123.27/24&lt;br /&gt;
  lo: 51.83.117.113/32 ; passerelle: 10.0.0.4 (ens18) ; DNS: 10.0.0.4&lt;br /&gt;
Cette operation remplace Netplan dans l&#039;invite, sans activer les interfaces Proxmox.&lt;br /&gt;
Confirmer (OUI/NON) : oui&lt;br /&gt;
[OK] Netplan ecrit et netplan generate valide : {&amp;quot;changed&amp;quot;: true, &amp;quot;backup&amp;quot;: true}&lt;br /&gt;
[OK] VM505 toujours isolee ; aucune activation des liens&lt;br /&gt;
&lt;br /&gt;
=== ÉTAPE 7/11 : activation-reseau ===&lt;br /&gt;
/usr/bin/python3 /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --network-enable --agent-timeout 300&lt;br /&gt;
[OK] Agent QEMU disponible&lt;br /&gt;
[OK] ajlsm-clone-init terminé avec succès&lt;br /&gt;
[OK] ARP DAD 10.0.0.43 sur vmbr2 (aucune reponse)&lt;br /&gt;
[OK] ARP DAD 192.168.123.27 sur vmbr1 (aucune reponse)&lt;br /&gt;
[OK] VM505 UUID=89aea8cb-9fd5-4b3b-9e06-a80cfa014f5b, clone et Netplan valides, reseau isole&lt;br /&gt;
Activer le reseau de cette VM (OUI/NON) : oui&lt;br /&gt;
[OK] ARP DAD 10.0.0.43 sur vmbr2 (aucune reponse)&lt;br /&gt;
[OK] ARP DAD 192.168.123.27 sur vmbr1 (aucune reponse)&lt;br /&gt;
[OK] Adresses, loopback, route, DNS et ping passerelle valides&lt;br /&gt;
[OK] VM505 : reseau actif et controle, onboot conforme au YAML&lt;br /&gt;
&lt;br /&gt;
=== ÉTAPE 8/11 : audit-ssh ===&lt;br /&gt;
/usr/bin/python3 /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --ssh-audit --agent-timeout 300&lt;br /&gt;
[OK] Clé ED25519 vérifiée via QEMU : 10.0.0.43&lt;br /&gt;
[OK] known_hosts actualisé avec sauvegarde conservée&lt;br /&gt;
=== Contrôle SSH, sans modification ===&lt;br /&gt;
Identité : mercure3.ajlsm.com&lt;br /&gt;
&lt;br /&gt;
Clés autorisées ajlsm :&lt;br /&gt;
4096 SHA256:zGdW2VjyzL/p30BjtNy6dzXIahBWTH9djZLc62IKCAk siva@MacBook-Pro-de-Sivakavi.local (RSA)&lt;br /&gt;
256 SHA256:lVtwxE0No+RZNyOXpf64JBCnMYIk9YaMw43clCV92hk jlarvers@MacBook-Pro.lan (ED25519)&lt;br /&gt;
256 SHA256:HAHGVQ2Afy6vGJpLhJ2vftXonwV31QNOiFHH6t5BfB4 modou-mbp (ED25519)&lt;br /&gt;
&lt;br /&gt;
Configuration effective SSH :&lt;br /&gt;
permitrootlogin prohibit-password&lt;br /&gt;
pubkeyauthentication yes&lt;br /&gt;
passwordauthentication yes&lt;br /&gt;
kbdinteractiveauthentication no&lt;br /&gt;
&lt;br /&gt;
Règles sudo pour ajlsm :&lt;br /&gt;
User ajlsm may run the following commands on mercure3.ajlsm.com:&lt;br /&gt;
    (ALL : ALL) ALL&lt;br /&gt;
&lt;br /&gt;
Etat du mot de passe ajlsm :&lt;br /&gt;
ajlsm P 2026-05-22 0 99999 7 -1&lt;br /&gt;
[OK] Connexion ajlsm par clé vérifiée.&lt;br /&gt;
&lt;br /&gt;
=== ÉTAPE 9/11 : securisation-ssh ===&lt;br /&gt;
/usr/bin/python3 /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --ssh-secure --agent-timeout 300&lt;br /&gt;
=== Contrôle SSH, sans modification ===&lt;br /&gt;
Identité : mercure3.ajlsm.com&lt;br /&gt;
&lt;br /&gt;
Clés autorisées ajlsm :&lt;br /&gt;
4096 SHA256:zGdW2VjyzL/p30BjtNy6dzXIahBWTH9djZLc62IKCAk siva@MacBook-Pro-de-Sivakavi.local (RSA)&lt;br /&gt;
256 SHA256:lVtwxE0No+RZNyOXpf64JBCnMYIk9YaMw43clCV92hk jlarvers@MacBook-Pro.lan (ED25519)&lt;br /&gt;
256 SHA256:HAHGVQ2Afy6vGJpLhJ2vftXonwV31QNOiFHH6t5BfB4 modou-mbp (ED25519)&lt;br /&gt;
&lt;br /&gt;
Configuration effective SSH :&lt;br /&gt;
permitrootlogin prohibit-password&lt;br /&gt;
pubkeyauthentication yes&lt;br /&gt;
passwordauthentication yes&lt;br /&gt;
kbdinteractiveauthentication no&lt;br /&gt;
&lt;br /&gt;
Règles sudo pour ajlsm :&lt;br /&gt;
User ajlsm may run the following commands on mercure3.ajlsm.com:&lt;br /&gt;
    (ALL : ALL) ALL&lt;br /&gt;
&lt;br /&gt;
Etat du mot de passe ajlsm :&lt;br /&gt;
ajlsm P 2026-05-22 0 99999 7 -1&lt;br /&gt;
[OK] Connexion ajlsm par clé vérifiée.&lt;br /&gt;
Appliquer PasswordAuthentication no et root par clé seulement [oui/non] : oui&lt;br /&gt;
[OK] SSH sécurisé ; root reste autorisé par clé.&lt;br /&gt;
[OK] Connexions root et ajlsm par clé toujours fonctionnelles.&lt;br /&gt;
&lt;br /&gt;
=== ÉTAPE 10/11 : mot-de-passe ===&lt;br /&gt;
/usr/bin/python3 /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --password-ajlsm --agent-timeout 300&lt;br /&gt;
Ouvrir passwd ajlsm sur MERCURE3 [oui/non] : oui&lt;br /&gt;
Le mot de passe sera demandé deux fois par passwd sur la VM.&lt;br /&gt;
Il ne sera pas enregistré dans le script. Le reporter manuellement dans le fichier ODS.&lt;br /&gt;
New password: &lt;br /&gt;
Retype new password: &lt;br /&gt;
passwd: password updated successfully&lt;br /&gt;
Connection to 10.0.0.43 closed.&lt;br /&gt;
[OK] Mot de passe ajlsm modifié ; vérifier ensuite sudo -i depuis ajlsm.&lt;br /&gt;
&lt;br /&gt;
=== ÉTAPE 11/11 : tls ===&lt;br /&gt;
/usr/bin/python3 /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml --tls-apply --agent-timeout 300&lt;br /&gt;
mercure3.ajlsm.com&lt;br /&gt;
subject=CN=clone-89aea8cb-9fd.internal&lt;br /&gt;
X509v3 Subject Alternative Name: &lt;br /&gt;
    DNS:clone-89aea8cb-9fd.internal&lt;br /&gt;
&lt;br /&gt;
Initialiser le certificat TLS interne [oui/non] : oui&lt;br /&gt;
Initialisation TLS pour : mercure3.ajlsm.com&lt;br /&gt;
...+......+.+..+.......+...+.....+......++++++++++++++++++++++++++++++++++++++++++*.+....+...+..+......+.++++++++++++++++++++++++++++++++++++++++++*....+...............+.....+....+............+..+......+........................+.+.........+.....+......+....+...+++++&lt;br /&gt;
...+..........+...++++++++++++++++++++++++++++++++++++++++++*.+....+...+...+..............+............+.+........+.+...............+...........++++++++++++++++++++++++++++++++++++++++++*...+......+...+....+.................+....+..+...+....+.....+..........+......+.....................+...+...+.....+...+.+...+........+...+.......+..+..........+..+....+..+....+.........+...........+...................+......+.....+.............+..+.+...............+............+......+.....+.+.........+....................+.......+............+...+..+......+.+.........+..+.......+...+.................+.+.....+.+..............+.+...............+........+......+.........+.......+.....+....+..+.......+......+...........+...+......+.........+............+.+..+.......+......+.....+....+.....+.............+........+.........+.+............+......+.....+..........+......+.....+....+......+.....+.+...+..+............+......+......+....+...........+.+..+.+..............+............................+...+.....+.......+..+..........+.....+.......+....................+....+..+.......+..+....+.........+...........+.+.........+...........+....+.........+...........+..........+.....+......+.+.....+.......+..+......+...+++++&lt;br /&gt;
-----&lt;br /&gt;
Syntax OK&lt;br /&gt;
&lt;br /&gt;
Initialisation TLS terminée.&lt;br /&gt;
Sauvegarde : /etc/ssl/ajlsm/backup.ZSmJKspN&lt;br /&gt;
subject=CN=mercure3.ajlsm.com&lt;br /&gt;
notBefore=Oct 16 14:58:53 2026 GMT&lt;br /&gt;
notAfter=Oct 13 14:58:53 2036 GMT&lt;br /&gt;
subject=CN=mercure3.ajlsm.com&lt;br /&gt;
X509v3 Subject Alternative Name: &lt;br /&gt;
    DNS:mercure3.ajlsm.com&lt;br /&gt;
active&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[OK] Cycle technique terminé ; procéder aux vérifications finales.&lt;br /&gt;
root@Saturne3:~/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle# ssh ajlsm@10.0.0.43&lt;br /&gt;
sudo -i&lt;br /&gt;
hostname&lt;br /&gt;
df -hT /&lt;br /&gt;
Welcome to Ubuntu 26.04.1 LTS (GNU/Linux 7.0.0-38-generic x86_64)&lt;br /&gt;
&lt;br /&gt;
 * Documentation:  https://docs.ubuntu.com&lt;br /&gt;
 * Management:     https://landscape.canonical.com&lt;br /&gt;
 * Support:        https://ubuntu.com/pro&lt;br /&gt;
&lt;br /&gt;
 System information as of Fri Oct 16 05:00:42 PM CEST 2026&lt;br /&gt;
&lt;br /&gt;
  System load:  0.09              Processes:              193&lt;br /&gt;
  Usage of /:   8.2% of 96.34GB   Users logged in:        0&lt;br /&gt;
  Memory usage: 3%                IPv4 address for ens18: 10.0.0.43&lt;br /&gt;
  Swap usage:   0%&lt;br /&gt;
&lt;br /&gt;
 * Canonical Workshop gives developers fast, composable, reproducible, and&lt;br /&gt;
   secure developer environments that are perfect for agentic workflows.&lt;br /&gt;
&lt;br /&gt;
   https://ubuntu.com/workshop&lt;br /&gt;
&lt;br /&gt;
Expanded Security Maintenance for Applications is not enabled.&lt;br /&gt;
&lt;br /&gt;
1 update can be applied immediately.&lt;br /&gt;
To see these additional updates run: apt list --upgradable&lt;br /&gt;
&lt;br /&gt;
9 additional security updates can be applied with ESM Apps.&lt;br /&gt;
Learn more about enabling ESM Apps service at https://ubuntu.com/esm&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You have new mail.&lt;br /&gt;
Last login: Thu Oct 15 08:18:27 2026 from 10.40.0.2&lt;br /&gt;
ajlsm@mercure3:~$ sudo -i&lt;br /&gt;
[sudo: authenticate] Password:                     &lt;br /&gt;
root@mercure3:~# hostname&lt;br /&gt;
df -hT /&lt;br /&gt;
mercure3.ajlsm.com&lt;br /&gt;
Filesystem                        Type  Size  Used Avail Use% Mounted on&lt;br /&gt;
/dev/mapper/ubuntu--vg-ubuntu--lv ext4   97G  8.0G   85G   9% /&lt;br /&gt;
root@mercure3:~# exit&lt;br /&gt;
logout&lt;br /&gt;
ajlsm@mercure3:~$ exit&lt;br /&gt;
logout&lt;br /&gt;
Connection to 10.0.0.43 closed.&lt;br /&gt;
root@Saturne3:~# python3 -m zipfile -e \&lt;br /&gt;
  /root/ajlsm-deploy/archives/ajlsm-deploy-assistant.zip \&lt;br /&gt;
  /root/ajlsm-deploy/recettes/20261016&lt;br /&gt;
root@Saturne3:~# install -m 750 \&lt;br /&gt;
  /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-assistant/ajlsm-deploy-yaml \&lt;br /&gt;
  /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/ajlsm-deploy-yaml&lt;br /&gt;
root@Saturne3:~# cd /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle &amp;amp;&amp;amp;&lt;br /&gt;
./ajlsm-deploy-yaml /etc/ajlsm/deploy/projets/mercure3.yaml --check&lt;br /&gt;
[OK] Valeurs YAML valides. Aucun fichier modifié, aucun contrôle d’infrastructure effectué.&lt;br /&gt;
root@Saturne3:~/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle# ./ajlsm-deploy-yaml /etc/ajlsm/deploy/projets/mercure3.yaml --review \&lt;br /&gt;
  --output /root/ajlsm-deploy/recettes/20261016/mercure3-relecture.yaml&lt;br /&gt;
Assistant local : ANNULER permet de quitter sans enregistrer.&lt;br /&gt;
Les commentaires du fichier source restent dans l’original ; la copie sera réécrite en YAML.&lt;br /&gt;
&lt;br /&gt;
projet.code — texte obligatoire ; syntaxe : [a-z0-9][a-z0-9_-]*&lt;br /&gt;
Valeur actuelle : mercure3&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
projet.nom — texte obligatoire&lt;br /&gt;
Valeur actuelle : MERCURE3&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
projet.environnement — interne, client ou prod&lt;br /&gt;
Valeur actuelle : interne&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
proxmox.serveur — texte obligatoire ; syntaxe : [A-Za-z0-9][A-Za-z0-9.-]*&lt;br /&gt;
Valeur actuelle : Saturne3&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
proxmox.template_vmid — entier strictement positif&lt;br /&gt;
Valeur actuelle : 506&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
proxmox.vmid — null ou auto = automatique ; sinon entier positif&lt;br /&gt;
Valeur actuelle : null&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
proxmox.nom_vm — texte obligatoire ; syntaxe : [A-Za-z0-9][A-Za-z0-9.-]*&lt;br /&gt;
Valeur actuelle : MERCURE3&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
proxmox.cpu.sockets — entier strictement positif&lt;br /&gt;
Valeur actuelle : 1&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
proxmox.cpu.cores — entier strictement positif&lt;br /&gt;
Valeur actuelle : 8&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
proxmox.memoire.maximale_mib — entier strictement positif&lt;br /&gt;
Valeur actuelle : 24576&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
proxmox.memoire.minimale_mib — entier strictement positif&lt;br /&gt;
Valeur actuelle : 16384&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
proxmox.disque_systeme.stockage — texte obligatoire ; syntaxe : [A-Za-z0-9][A-Za-z0-9_.-]*&lt;br /&gt;
Valeur actuelle : local-zfs&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
proxmox.disque_systeme.taille_gib — entier strictement positif&lt;br /&gt;
Valeur actuelle : 100&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
proxmox.disque_systeme.etendre_volume_racine — true ou false&lt;br /&gt;
Valeur actuelle : true&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
proxmox.demarrage_auto — true ou false&lt;br /&gt;
Valeur actuelle : true&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
proxmox.tags — interne, client, prod séparés par virgules ; [] = aucun&lt;br /&gt;
Valeur actuelle : [interne]&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
systeme.hostname — nom DNS en minuscules&lt;br /&gt;
Valeur actuelle : mercure3.ajlsm.com&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
reseau.interfaces[0].nom — texte obligatoire ; syntaxe : net[0-9]+&lt;br /&gt;
Valeur actuelle : net0&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
reseau.interfaces[0].bridge — texte obligatoire ; syntaxe : [A-Za-z0-9_.-]{1,15}&lt;br /&gt;
Valeur actuelle : vmbr2&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
reseau.interfaces[0].systeme — texte obligatoire ; syntaxe : ens[0-9]+&lt;br /&gt;
Valeur actuelle : ens18&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
reseau.interfaces[0].ipv4 — IPv4/CIDR, ex. 10.0.0.43/24&lt;br /&gt;
Valeur actuelle : 10.0.0.43/24&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
reseau.interfaces[1].nom — texte obligatoire ; syntaxe : net[0-9]+&lt;br /&gt;
Valeur actuelle : net1&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
reseau.interfaces[1].bridge — texte obligatoire ; syntaxe : [A-Za-z0-9_.-]{1,15}&lt;br /&gt;
Valeur actuelle : vmbr1&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
reseau.interfaces[1].systeme — texte obligatoire ; syntaxe : ens[0-9]+&lt;br /&gt;
Valeur actuelle : ens19&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
reseau.interfaces[1].ipv4 — IPv4/CIDR, ex. 10.0.0.43/24&lt;br /&gt;
Valeur actuelle : 192.168.123.27/24&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
reseau.loopback.ipv4 — IPv4/CIDR, ex. 10.0.0.43/24&lt;br /&gt;
Valeur actuelle : 51.83.117.113/32&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
reseau.passerelle.ipv4 — IPv4 sans préfixe&lt;br /&gt;
Valeur actuelle : 10.0.0.4&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
reseau.passerelle.interface — texte obligatoire ; syntaxe : ens[0-9]+&lt;br /&gt;
Valeur actuelle : ens18&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
reseau.dns — IPv4 sans préfixes, séparées par virgules&lt;br /&gt;
Valeur actuelle : [10.0.0.4]&lt;br /&gt;
Nouvelle valeur (Entrée = conserver) : &lt;br /&gt;
&lt;br /&gt;
=== PROJET PROPOSÉ ===&lt;br /&gt;
projet:&lt;br /&gt;
  code: mercure3&lt;br /&gt;
  nom: MERCURE3&lt;br /&gt;
  environnement: interne&lt;br /&gt;
proxmox:&lt;br /&gt;
  serveur: Saturne3&lt;br /&gt;
  template_vmid: 506&lt;br /&gt;
  vmid: null&lt;br /&gt;
  nom_vm: MERCURE3&lt;br /&gt;
  cpu:&lt;br /&gt;
    sockets: 1&lt;br /&gt;
    cores: 8&lt;br /&gt;
  memoire:&lt;br /&gt;
    maximale_mib: 24576&lt;br /&gt;
    minimale_mib: 16384&lt;br /&gt;
  disque_systeme:&lt;br /&gt;
    stockage: local-zfs&lt;br /&gt;
    taille_gib: 100&lt;br /&gt;
    etendre_volume_racine: true&lt;br /&gt;
  demarrage_auto: true&lt;br /&gt;
  tags:&lt;br /&gt;
  - interne&lt;br /&gt;
systeme:&lt;br /&gt;
  hostname: mercure3.ajlsm.com&lt;br /&gt;
reseau:&lt;br /&gt;
  interfaces:&lt;br /&gt;
  - nom: net0&lt;br /&gt;
    bridge: vmbr2&lt;br /&gt;
    systeme: ens18&lt;br /&gt;
    ipv4: 10.0.0.43/24&lt;br /&gt;
  - nom: net1&lt;br /&gt;
    bridge: vmbr1&lt;br /&gt;
    systeme: ens19&lt;br /&gt;
    ipv4: 192.168.123.27/24&lt;br /&gt;
  loopback:&lt;br /&gt;
    ipv4: 51.83.117.113/32&lt;br /&gt;
  passerelle:&lt;br /&gt;
    ipv4: 10.0.0.4&lt;br /&gt;
    interface: ens18&lt;br /&gt;
  dns:&lt;br /&gt;
  - 10.0.0.4&lt;br /&gt;
&lt;br /&gt;
[OK] Valeurs et cohérence YAML validées par le validateur du déploiement.&lt;br /&gt;
[NON VÉRIFIÉS] DNS, OPNsense, Ansible, objets Proxmox et disponibilité des IP.&lt;br /&gt;
Enregistrer la nouvelle copie dans /root/ajlsm-deploy/recettes/20261016/mercure3-relecture.yaml ? OUI/NON : oui&lt;br /&gt;
[ENREGISTRÉ] /root/ajlsm-deploy/recettes/20261016/mercure3-relecture.yaml&lt;br /&gt;
Contrôle Proxmox en lecture seule, à lancer sur le nœud cible avant un nouveau déploiement :&lt;br /&gt;
/root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/ajlsm-deploy-check /root/ajlsm-deploy/recettes/20261016/mercure3-relecture.yaml&lt;br /&gt;
root@Saturne3:~/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle# Read from remote host 141.95.206.118: Connection reset by peer&lt;br /&gt;
Connection to 141.95.206.118 closed.&lt;br /&gt;
client_loop: send disconnect: Broken pipe&lt;br /&gt;
jlarvers@MacBook-Pro ~ % ssh saturne3&lt;br /&gt;
Linux Saturne3 7.0.14-23-pve #1 SMP PREEMPT_DYNAMIC PMX 7.0.14-23 (2026-10-07T20:25Z) x86_64&lt;br /&gt;
&lt;br /&gt;
The programs included with the Debian GNU/Linux system are free software;&lt;br /&gt;
the exact distribution terms for each program are described in the&lt;br /&gt;
individual files in /usr/share/doc/*/copyright.&lt;br /&gt;
&lt;br /&gt;
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent&lt;br /&gt;
permitted by applicable law.&lt;br /&gt;
Last login: Fri Oct 16 16:43:10 2026 from 109.190.129.96&lt;br /&gt;
root@Saturne3:~# man -w ajlsm-deploy&lt;br /&gt;
/usr/local/man/man8/ajlsm-deploy.8&lt;br /&gt;
root@Saturne3:~# man -w ajlsm-deploy&lt;br /&gt;
/usr/local/man/man8/ajlsm-deploy.8&lt;br /&gt;
root@Saturne3:~# scp root@141.95.206.118:/usr/local/man/man8/ajlsm-deploy.8 ~/Downloads/ajlsm-deploy-existant.8&lt;br /&gt;
The authenticity of host &#039;141.95.206.118 (141.95.206.118)&#039; can&#039;t be established.&lt;br /&gt;
ED25519 key fingerprint is SHA256:GaOnRcly/RWj3rX8/2/Y/gdlagmDypNNvo0xRK1kQaE.&lt;br /&gt;
This host key is known by the following other names/addresses:&lt;br /&gt;
    ~/.ssh/known_hosts:21: [hashed name]&lt;br /&gt;
    ~/.ssh/known_hosts:26: [hashed name]&lt;br /&gt;
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes&lt;br /&gt;
Warning: Permanently added &#039;141.95.206.118&#039; (ED25519) to the list of known hosts.&lt;br /&gt;
scp: open local &amp;quot;/root/Downloads/ajlsm-deploy-existant.8&amp;quot;: No such file or directory&lt;br /&gt;
root@Saturne3:~# python3 -m zipfile -e \&lt;br /&gt;
  /root/ajlsm-deploy/archives/ajlsm-deploy-man.zip \&lt;br /&gt;
  /root/ajlsm-deploy/recettes/20261016 &amp;amp;&amp;amp;&lt;br /&gt;
cd /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-man&lt;br /&gt;
root@Saturne3:~/ajlsm-deploy/recettes/20261016/ajlsm-deploy-man# SAUVEGARDE_MAN=$(mktemp -d /root/ajlsm-deploy/archives/man-avant-20261016.XXXXXX)&lt;br /&gt;
&lt;br /&gt;
for NOM_MAN in ajlsm-deploy ajlsm-deploy-cycle ajlsm-deploy-yaml ajlsm-deploy-check ajlsm-deploy-resources; do&lt;br /&gt;
  for SUFFIXE_MAN in .8 .8.gz; do&lt;br /&gt;
    PAGE_MAN=&amp;quot;/usr/local/man/man8/$NOM_MAN$SUFFIXE_MAN&amp;quot;&lt;br /&gt;
    if [ -e &amp;quot;$PAGE_MAN&amp;quot; ] || [ -L &amp;quot;$PAGE_MAN&amp;quot; ]; then&lt;br /&gt;
      cp -a &amp;quot;$PAGE_MAN&amp;quot; &amp;quot;$SAUVEGARDE_MAN/&amp;quot; || break 2&lt;br /&gt;
    fi&lt;br /&gt;
  done&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
printf &#039;Sauvegarde : %s\n&#039; &amp;quot;$SAUVEGARDE_MAN&amp;quot;&lt;br /&gt;
Sauvegarde : /root/ajlsm-deploy/archives/man-avant-20261016.WiJHQn&lt;br /&gt;
root@Saturne3:~/ajlsm-deploy/recettes/20261016/ajlsm-deploy-man# install -d -m 755 /usr/local/man/man8&lt;br /&gt;
&lt;br /&gt;
for NOM_MAN in ajlsm-deploy ajlsm-deploy-cycle ajlsm-deploy-yaml ajlsm-deploy-check ajlsm-deploy-resources; do&lt;br /&gt;
  install -m 644 &amp;quot;man8/$NOM_MAN.8&amp;quot; &amp;quot;/usr/local/man/man8/$NOM_MAN.8&amp;quot; || break&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
if command -v mandb &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then&lt;br /&gt;
  mandb&lt;br /&gt;
fi&lt;br /&gt;
Purging old database entries in /usr/share/man...&lt;br /&gt;
Processing manual pages under /usr/share/man...&lt;br /&gt;
Checking for stray cats under /usr/share/man...&lt;br /&gt;
Checking for stray cats under /var/cache/man...&lt;br /&gt;
Purging old database entries in /usr/share/man/pl...&lt;br /&gt;
Processing manual pages under /usr/share/man/pl...&lt;br /&gt;
Checking for stray cats under /usr/share/man/pl...&lt;br /&gt;
Checking for stray cats under /var/cache/man/pl...&lt;br /&gt;
Purging old database entries in /usr/share/man/ru...&lt;br /&gt;
Processing manual pages under /usr/share/man/ru...&lt;br /&gt;
Checking for stray cats under /usr/share/man/ru...&lt;br /&gt;
Checking for stray cats under /var/cache/man/ru...&lt;br /&gt;
Purging old database entries in /usr/share/man/id...&lt;br /&gt;
Processing manual pages under /usr/share/man/id...&lt;br /&gt;
Checking for stray cats under /usr/share/man/id...&lt;br /&gt;
Checking for stray cats under /var/cache/man/id...&lt;br /&gt;
Purging old database entries in /usr/share/man/es...&lt;br /&gt;
Processing manual pages under /usr/share/man/es...&lt;br /&gt;
Checking for stray cats under /usr/share/man/es...&lt;br /&gt;
Checking for stray cats under /var/cache/man/es...&lt;br /&gt;
Purging old database entries in /usr/share/man/zh_TW...&lt;br /&gt;
Processing manual pages under /usr/share/man/zh_TW...&lt;br /&gt;
Checking for stray cats under /usr/share/man/zh_TW...&lt;br /&gt;
Checking for stray cats under /var/cache/man/zh_TW...&lt;br /&gt;
Purging old database entries in /usr/share/man/sl...&lt;br /&gt;
Processing manual pages under /usr/share/man/sl...&lt;br /&gt;
Checking for stray cats under /usr/share/man/sl...&lt;br /&gt;
Checking for stray cats under /var/cache/man/sl...&lt;br /&gt;
Purging old database entries in /usr/share/man/pt...&lt;br /&gt;
Processing manual pages under /usr/share/man/pt...&lt;br /&gt;
Checking for stray cats under /usr/share/man/pt...&lt;br /&gt;
Checking for stray cats under /var/cache/man/pt...&lt;br /&gt;
Purging old database entries in /usr/share/man/hr...&lt;br /&gt;
Processing manual pages under /usr/share/man/hr...&lt;br /&gt;
Checking for stray cats under /usr/share/man/hr...&lt;br /&gt;
Checking for stray cats under /var/cache/man/hr...&lt;br /&gt;
Purging old database entries in /usr/share/man/pt_BR...&lt;br /&gt;
Processing manual pages under /usr/share/man/pt_BR...&lt;br /&gt;
Checking for stray cats under /usr/share/man/pt_BR...&lt;br /&gt;
Checking for stray cats under /var/cache/man/pt_BR...&lt;br /&gt;
Purging old database entries in /usr/share/man/hu...&lt;br /&gt;
Processing manual pages under /usr/share/man/hu...&lt;br /&gt;
Checking for stray cats under /usr/share/man/hu...&lt;br /&gt;
Checking for stray cats under /var/cache/man/hu...&lt;br /&gt;
Purging old database entries in /usr/share/man/da...&lt;br /&gt;
Processing manual pages under /usr/share/man/da...&lt;br /&gt;
Checking for stray cats under /usr/share/man/da...&lt;br /&gt;
Checking for stray cats under /var/cache/man/da...&lt;br /&gt;
Purging old database entries in /usr/share/man/cs...&lt;br /&gt;
Processing manual pages under /usr/share/man/cs...&lt;br /&gt;
Checking for stray cats under /usr/share/man/cs...&lt;br /&gt;
Checking for stray cats under /var/cache/man/cs...&lt;br /&gt;
Purging old database entries in /usr/share/man/tr...&lt;br /&gt;
Processing manual pages under /usr/share/man/tr...&lt;br /&gt;
Checking for stray cats under /usr/share/man/tr...&lt;br /&gt;
Checking for stray cats under /var/cache/man/tr...&lt;br /&gt;
Purging old database entries in /usr/share/man/fr...&lt;br /&gt;
Processing manual pages under /usr/share/man/fr...&lt;br /&gt;
Checking for stray cats under /usr/share/man/fr...&lt;br /&gt;
Checking for stray cats under /var/cache/man/fr...&lt;br /&gt;
Purging old database entries in /usr/share/man/nl...&lt;br /&gt;
Processing manual pages under /usr/share/man/nl...&lt;br /&gt;
Checking for stray cats under /usr/share/man/nl...&lt;br /&gt;
Checking for stray cats under /var/cache/man/nl...&lt;br /&gt;
Purging old database entries in /usr/share/man/ko...&lt;br /&gt;
Processing manual pages under /usr/share/man/ko...&lt;br /&gt;
Checking for stray cats under /usr/share/man/ko...&lt;br /&gt;
Checking for stray cats under /var/cache/man/ko...&lt;br /&gt;
Purging old database entries in /usr/share/man/zh_CN...&lt;br /&gt;
Processing manual pages under /usr/share/man/zh_CN...&lt;br /&gt;
Checking for stray cats under /usr/share/man/zh_CN...&lt;br /&gt;
Checking for stray cats under /var/cache/man/zh_CN...&lt;br /&gt;
Purging old database entries in /usr/share/man/sv...&lt;br /&gt;
Processing manual pages under /usr/share/man/sv...&lt;br /&gt;
Checking for stray cats under /usr/share/man/sv...&lt;br /&gt;
Checking for stray cats under /var/cache/man/sv...&lt;br /&gt;
Purging old database entries in /usr/share/man/ro...&lt;br /&gt;
Processing manual pages under /usr/share/man/ro...&lt;br /&gt;
Checking for stray cats under /usr/share/man/ro...&lt;br /&gt;
Checking for stray cats under /var/cache/man/ro...&lt;br /&gt;
Purging old database entries in /usr/share/man/uk...&lt;br /&gt;
Processing manual pages under /usr/share/man/uk...&lt;br /&gt;
Checking for stray cats under /usr/share/man/uk...&lt;br /&gt;
Checking for stray cats under /var/cache/man/uk...&lt;br /&gt;
Purging old database entries in /usr/share/man/sr...&lt;br /&gt;
Processing manual pages under /usr/share/man/sr...&lt;br /&gt;
Checking for stray cats under /usr/share/man/sr...&lt;br /&gt;
Checking for stray cats under /var/cache/man/sr...&lt;br /&gt;
Purging old database entries in /usr/share/man/ja...&lt;br /&gt;
Processing manual pages under /usr/share/man/ja...&lt;br /&gt;
Checking for stray cats under /usr/share/man/ja...&lt;br /&gt;
Checking for stray cats under /var/cache/man/ja...&lt;br /&gt;
Purging old database entries in /usr/share/man/de...&lt;br /&gt;
Processing manual pages under /usr/share/man/de...&lt;br /&gt;
Checking for stray cats under /usr/share/man/de...&lt;br /&gt;
Checking for stray cats under /var/cache/man/de...&lt;br /&gt;
Purging old database entries in /usr/share/man/fi...&lt;br /&gt;
Processing manual pages under /usr/share/man/fi...&lt;br /&gt;
Checking for stray cats under /usr/share/man/fi...&lt;br /&gt;
Checking for stray cats under /var/cache/man/fi...&lt;br /&gt;
Purging old database entries in /usr/share/man/it...&lt;br /&gt;
Processing manual pages under /usr/share/man/it...&lt;br /&gt;
Checking for stray cats under /usr/share/man/it...&lt;br /&gt;
Checking for stray cats under /var/cache/man/it...&lt;br /&gt;
Purging old database entries in /usr/local/man...&lt;br /&gt;
Processing manual pages under /usr/local/man...&lt;br /&gt;
Updating index cache for path `/usr/local/man/man8&#039;. Wait...done.&lt;br /&gt;
Checking for stray cats under /usr/local/man...&lt;br /&gt;
Checking for stray cats under /var/cache/man/oldlocal...&lt;br /&gt;
1 man subdirectory contained newer manual pages.&lt;br /&gt;
5 manual pages were added.&lt;br /&gt;
0 stray cats were added.&lt;br /&gt;
0 old database entries were purged.&lt;br /&gt;
root@Saturne3:~/ajlsm-deploy/recettes/20261016/ajlsm-deploy-man# man -w ajlsm-deploy&lt;br /&gt;
man 8 ajlsm-deploy&lt;br /&gt;
man 8 ajlsm-deploy-cycle&lt;br /&gt;
man 8 ajlsm-deploy-yaml&lt;br /&gt;
/usr/local/man/man8/ajlsm-deploy.8&lt;br /&gt;
&lt;br /&gt;
AJLSM-DEPLOY(8)                                     Administration système                                     AJLSM-DEPLOY(8)&lt;br /&gt;
&lt;br /&gt;
NOM&lt;br /&gt;
       ajlsm-deploy - déployer une VM Proxmox par phases contrôlées&lt;br /&gt;
&lt;br /&gt;
SYNOPSIS&lt;br /&gt;
       ajlsm-deploy projet.yaml PHASE [--agent-timeout secondes]&lt;br /&gt;
       ajlsm-deploy-check projet.yaml [--phase proxmox] [--yaml-only]&lt;br /&gt;
       ajlsm-deploy-resources projet.yaml (--dry-run | --apply)&lt;br /&gt;
&lt;br /&gt;
DESCRIPTION&lt;br /&gt;
       Programme  à  exécuter  sur  le  nœud Proxmox cible, avec les droits administrateur. Chaque invocation traite une seule&lt;br /&gt;
       phase.  Le YAML est validé avant les commandes externes.&lt;br /&gt;
&lt;br /&gt;
       Après succès, les suggestions affichent les commandes de simulation et d&#039;exécution de la prochaine étape, ou de l&#039;étape&lt;br /&gt;
       simulée.  Les étapes sans simulation dédiée le signalent explicitement.  Ces suggestions ne sont jamais  exécutées  au‐&lt;br /&gt;
       tomatiquement.  Elles décrivent l&#039;ordre théorique, sans mémoriser l&#039;état du cycle.&lt;br /&gt;
&lt;br /&gt;
       Pour  enchaîner les onze étapes sans en oublier, utiliser ajlsm-deploy-cycle(8).  Ce lanceur conserve les confirmations&lt;br /&gt;
       et les saisies interactives.&lt;br /&gt;
&lt;br /&gt;
ORDRE DES PHASES&lt;br /&gt;
       1. --clone&lt;br /&gt;
              Créer le clone complet, désactiver onboot, isoler les interfaces, vérifier l&#039;arrêt et les  adresses  MAC.  Aucun&lt;br /&gt;
              démarrage.  Simulation : --dry-run, qui comprend les précontrôles.&lt;br /&gt;
&lt;br /&gt;
       2. --configure-resources&lt;br /&gt;
              Configurer  et vérifier CPU, mémoire, balloon et disque scsi0.  Exige une VM arrêtée, onboot désactivé et inter‐&lt;br /&gt;
              faces isolées.  La réduction du disque est interdite.  Simulation : --resources-dry-run.&lt;br /&gt;
&lt;br /&gt;
       3. --first-boot-apply&lt;br /&gt;
              Démarrer le clone isolé, attendre l&#039;agent QEMU et ajlsm-clone-init, puis vérifier les identités  attendues.   Si&lt;br /&gt;
              la VM tourne déjà, reprendre les contrôles sans redémarrage.  Simulation : --first-boot-dry-run.&lt;br /&gt;
&lt;br /&gt;
       4. --root-grow-apply&lt;br /&gt;
              Après  le  premier démarrage et avant la personnalisation système, étendre la partition, le PV LVM, le LV racine&lt;br /&gt;
              et ext4.  Cette étape dépend de etendre_volume_racine dans le YAML.  Simulation : --root-grow-dry-run.&lt;br /&gt;
&lt;br /&gt;
       5. --system-apply&lt;br /&gt;
              Personnaliser hostname, hosts et machine-id, redémarrer isolé et vérifier l&#039;identité active. Respecter le  jour‐&lt;br /&gt;
              nal de transaction.  Simulation : --system-dry-run.&lt;br /&gt;
&lt;br /&gt;
       6. --network-apply&lt;br /&gt;
              Sauvegarder  et  écrire Netplan dans l&#039;invité, puis exécuter netplan generate. Les liens Proxmox restent isolés.&lt;br /&gt;
              Simulation : --network-dry-run.&lt;br /&gt;
&lt;br /&gt;
       7. --network-enable&lt;br /&gt;
              Contrôler identité, configuration et conflits ARP, activer les liens, vérifier adresses, loopback, route, DNS et&lt;br /&gt;
              passerelle, puis appliquer demarrage_auto.  Un mécanisme de repli tente de rétablir l&#039;isolation en cas  d&#039;échec.&lt;br /&gt;
              Simulation : --network-enable-dry-run.&lt;br /&gt;
&lt;br /&gt;
       8. --ssh-audit&lt;br /&gt;
              Comparer  la  clé  ED25519 lue via QEMU à celle exposée sur le réseau, actualiser known_hosts après concordance,&lt;br /&gt;
              puis vérifier les accès, clés autorisées, sudo et état du compte ajlsm.  Aucune simulation dédiée.&lt;br /&gt;
&lt;br /&gt;
       9. --ssh-secure&lt;br /&gt;
              Après audit et confirmation, désactiver l&#039;authentification SSH par mot de passe, conserver root par  clé,  véri‐&lt;br /&gt;
              fier  la  configuration,  recharger  SSH  et  contrôler les connexions root et ajlsm par clé.  Aucune simulation&lt;br /&gt;
              dédiée.&lt;br /&gt;
&lt;br /&gt;
       10. --password-ajlsm&lt;br /&gt;
              Ouvrir passwd pour ajlsm dans la VM avec double saisie native masquée.  Un terminal interactif est  obligatoire.&lt;br /&gt;
              Le mot de passe n&#039;est pas placé dans le YAML ni la ligne de commande.  Aucune simulation dédiée.&lt;br /&gt;
&lt;br /&gt;
       11. --tls-apply&lt;br /&gt;
              Vérifier  le  certificat TLS interne. Si CN et SAN correspondent déjà au hostname, ne pas réinitialiser.  Sinon,&lt;br /&gt;
              après confirmation, appeler ajlsm-init-tls.sh dans la VM, puis vérifier certificat, syntaxe  Apache  et  service&lt;br /&gt;
              actif.  Aucune simulation dédiée.&lt;br /&gt;
&lt;br /&gt;
OPTIONS COMMUNES&lt;br /&gt;
       --agent-timeout secondes&lt;br /&gt;
              Entier  strictement  positif,  défaut 300.  Délai transmis aux attentes utilisant l&#039;agent QEMU.  Il ne constitue&lt;br /&gt;
 Manual page ajlsm-deploy(8) line 1/219 32% (press h for help or q to quit)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 12. État des validations et limites ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Date / source !! Vérification !! Portée&lt;br /&gt;
|-&lt;br /&gt;
| 15/10/2026, page historique || Déploiements initiaux jusqu’à l’activation réseau || Résultats historiques conservés ; ne décrivent pas à eux seuls le cycle actuel&lt;br /&gt;
|-&lt;br /&gt;
| 15/10/2026, page historique || Comparaison ED25519, clés divergentes ou malformées, préservation de known_hosts || Tests isolés rapportés dans la documentation reçue, non rejoués lors de cette consolidation&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, tests locaux du lot cycle || Ordre des 11 étapes, arrêt sur refus/erreur, reprise et suggestions || 8 tests réussis, incluant des sous-cas ; sous-processus des phases simulés&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, sorties Saturne3 transmises || Cycle technique complet sur un nouveau clone MERCURE3 || Terminé sans erreur signalée, extension racine incluse&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, sorties invitées transmises || SSH ajlsm, sudo, hostname et racine ext4 || Confirmés ; mercure3.ajlsm.com et 97 Gio pour /&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, tests locaux assistant || Création, correction, copie, validation et annulation || 14 tests réussis, saisies simulées&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, sortie Saturne3 transmise || Assistant --check sur mercure3.yaml || Valeurs YAML valides ; aucune écriture ni validation externe&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, vérification locale des modèles || Modèle vierge complété par l’assistant || Paramètres identiques à la référence MERCURE3 ; original intact&lt;br /&gt;
|-&lt;br /&gt;
| À réaliser || Essai réel du mécanisme de repli après échec d’activation réseau || Non confirmé ; le succès du parcours nominal ne valide pas ce scénario&lt;br /&gt;
|-&lt;br /&gt;
| À réaliser || Vérifications automatiques DNS, OPNsense, Ansible et recette applicative || Hors périmètre actuel&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le message de fin du cycle signifie que ses phases ont retourné un succès. Il ne vaut pas validation des applications ni détection de toutes les défaillances possibles. Conserver les vérifications finales et les limites propres aux phases.&lt;br /&gt;
&lt;br /&gt;
== 13. Réconciliation avec la page du 15 octobre ==&lt;br /&gt;
&lt;br /&gt;
L’original reçu est conservé intégralement dans historique/guide-20261015.mediawiki. Il sert de trace, pas de seconde procédure opérationnelle concurrente.&lt;br /&gt;
&lt;br /&gt;
Le présent document remplace les indications opérationnelles anciennes :&lt;br /&gt;
* confirmations CLONER/APPLIQUER/DEMARRER remplacées par OUI/NON ;&lt;br /&gt;
* parcours manuel seul remplacé par le choix entre mode manuel et cycle interactif ;&lt;br /&gt;
* liste des étapes incluant l’extension racine, SSH, mot de passe et TLS ;&lt;br /&gt;
* extension racine et cycle complet désormais validés sur la recette du 16 octobre ;&lt;br /&gt;
* suggestions manuelles affichant les deux commandes disponibles, sans oublier l’extension racine ;&lt;br /&gt;
* création et relecture du YAML par l’assistant, sans écraser l’original ;&lt;br /&gt;
* ajout du modèle vierge et de la référence MERCURE3 renseignée ;&lt;br /&gt;
* séparation explicite des scripts installés, du lot de recette, du manuel historique et de la future installation.&lt;br /&gt;
&lt;br /&gt;
Les détails encore utiles de l’ancienne page sur l’isolation, les transactions, ED25519, les sauvegardes, le README applicatif et les limites de validation sont repris ci-dessus. Une nouvelle mise à jour fonctionnelle doit modifier cette procédure directement plutôt que superposer une nouvelle section corrective à une ancienne procédure contradictoire.&lt;br /&gt;
&lt;br /&gt;
== 14. Suites prévues ==&lt;br /&gt;
&lt;br /&gt;
Prévoir les paramètres NFS, sites Apache2, Pleade, Drupal et Matomo dans le même YAML lorsque leurs exigences seront définies. Modifier ensemble le schéma, l’assistant, les modèles, les précontrôles, les phases et leur documentation. Documenter les références aux secrets plutôt que leurs valeurs.&lt;br /&gt;
&lt;br /&gt;
L’intégration des contrôles DNS, OPNsense et Ansible précédera une déclaration automatisée de disponibilité du projet. Le modèle actuel ne contient pas encore ces nouvelles sections.&lt;br /&gt;
&lt;br /&gt;
[[Catégorie:Infrastructure]]&lt;br /&gt;
[[Catégorie:Proxmox]]&lt;br /&gt;
[[Catégorie:Déploiement]]&lt;br /&gt;
[[Catégorie:AJLSM]]&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=D%C3%A9ploiement_technique_d%E2%80%99une_VM_AJLSM&amp;diff=6494</id>
		<title>Déploiement technique d’une VM AJLSM</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=D%C3%A9ploiement_technique_d%E2%80%99une_VM_AJLSM&amp;diff=6494"/>
		<updated>2026-10-16T16:21:51Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : /* 5.2. Compléter le modèle vierge */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= AJLSM-DEPLOY — Déploiement automatisé des VM Proxmox =&lt;br /&gt;
&lt;br /&gt;
Document consolidé au 16 octobre 2026. Cette procédure réunit la page du 15 octobre et la recette actuelle. Elle remplace leurs indications opérationnelles divergentes. L’original du 15 octobre reste archivé séparément.&lt;br /&gt;
&lt;br /&gt;
Référence technique : scripts reçus de Saturne3, puis lot de recette avec lanceur du cycle et assistant YAML.&lt;br /&gt;
&lt;br /&gt;
== 1. Périmètre et résultat de la recette ==&lt;br /&gt;
&lt;br /&gt;
Le cycle technique a été exécuté sur MERCURE3 sans erreur signalée. Les vérifications finales transmises confirment :&lt;br /&gt;
* connexion SSH avec le compte ajlsm ;&lt;br /&gt;
* élévation sudo avec le mot de passe défini pendant le cycle ;&lt;br /&gt;
* hostname mercure3.ajlsm.com ;&lt;br /&gt;
* volume racine ext4 de 97 Gio, dont 85 Gio disponibles lors du contrôle.&lt;br /&gt;
&lt;br /&gt;
Le cycle couvre le clonage, les ressources, l’initialisation du clone, l’extension de la racine, l’identité système, le réseau, SSH, le mot de passe et le certificat TLS interne.&lt;br /&gt;
&lt;br /&gt;
NFS, les configurations applicatives Apache2, Pleade, Drupal et Matomo ne font pas encore partie de ce cycle. Certains logiciels peuvent déjà être présents dans le modèle : leur présence ne constitue pas une configuration applicative du projet.&lt;br /&gt;
&lt;br /&gt;
== 2. Où exécuter les commandes ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Machine !! Rôle !! Exemple d’invite&lt;br /&gt;
|-&lt;br /&gt;
| Mac de l’administrateur || Transfert des archives par scp || Invite locale du Mac&lt;br /&gt;
|-&lt;br /&gt;
| Saturne3 || Préparation YAML, scripts Proxmox et cycle || root@Saturne3&lt;br /&gt;
|-&lt;br /&gt;
| MERCURE3 || Vérifications dans la VM || ajlsm@mercure3 ou root@mercure3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les scripts de déploiement sont exécutés sur Saturne3, pas dans MERCURE3.&lt;br /&gt;
Après « ssh ajlsm@10.0.0.43 », attendre l’invite de la VM avant de saisir les commandes suivantes.&lt;br /&gt;
Pour revenir de root@mercure3 à Saturne3 : un exit quitte sudo, puis un second exit ferme SSH.&lt;br /&gt;
&lt;br /&gt;
== 3. Organisation des fichiers ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/root/ajlsm-deploy/&lt;br /&gt;
  archives/                         Archives reçues, conservées comme références&lt;br /&gt;
  recettes/20261016/&lt;br /&gt;
    ajlsm-deploy-cycle/             Lot technique validé et assistant ajouté&lt;br /&gt;
    ajlsm-deploy-assistant/         Distribution de l’assistant et tests&lt;br /&gt;
    ajlsm-deploy-documentation/     Présent guide et modèles YAML&lt;br /&gt;
&lt;br /&gt;
/etc/ajlsm/deploy/projets/mercure3.yaml   Configuration actuellement utilisée&lt;br /&gt;
/usr/local/sbin/                        Scripts installés antérieurement&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le lot de recette contient ajlsm-deploy, ajlsm-deploy-check, ajlsm-deploy-resources, ajlsm-deploy-cycle et les modules ajlsm_deploy_common.py, ajlsm_deploy_rootgrow.py et ajlsm_deploy_postconfig.py. L’assistant ajlsm-deploy-yaml a été ajouté à ce même dossier.&lt;br /&gt;
&lt;br /&gt;
Conserver exécutables et modules ensemble. Utiliser les chemins ./ depuis le dossier de recette pour ne pas appeler une ancienne version de /usr/local/sbin.&lt;br /&gt;
Les anciennes archives « ajlsm-deploy-revise » et « correction-suggestions » ne sont pas la référence courante : elles précèdent les phases supplémentaires reçues dans l’archive serveur.&lt;br /&gt;
&lt;br /&gt;
Prérequis : Python 3.9 ou supérieur, PyYAML 6, outils Proxmox sur le nœud cible et prérequis du modèle AJLSM. Les phases invitées utilisent notamment l’agent QEMU, ajlsm-clone-init, Python, systemd et Netplan. L’extension actuelle cible ext4/LVM sur /dev/sda3, avec un seul PV et un seul LV.&lt;br /&gt;
&lt;br /&gt;
== 4. Les deux fichiers de préconfiguration ==&lt;br /&gt;
&lt;br /&gt;
=== 4.1. projet-vierge.yaml ===&lt;br /&gt;
&lt;br /&gt;
Ce modèle reprend toute la structure actuelle sans valeur opérationnelle préremplie. Chaque champ doit être renseigné. Seul proxmox.vmid peut rester null : il signifie alors attribution automatique.&lt;br /&gt;
&lt;br /&gt;
Le modèle comporte deux interfaces dont les valeurs sont null. Adapter le nombre d’interfaces avant la saisie si nécessaire. Pour déterminer ce nombre par les questions de l’assistant, utiliser plutôt le mode --new.&lt;br /&gt;
&lt;br /&gt;
Un modèle vierge est volontairement refusé par --check. Il ne doit jamais être passé directement au lanceur du cycle.&lt;br /&gt;
&lt;br /&gt;
=== 4.2. mercure3-reference.yaml ===&lt;br /&gt;
&lt;br /&gt;
Ce fichier conserve les valeurs du projet validé : modèle 506 sur Saturne3, nom MERCURE3, 8 vCPU, 24576 Mio de RAM maximale, 16384 Mio minimale, disque 100 Gio, extension racine activée et paramètres réseau du projet.&lt;br /&gt;
&lt;br /&gt;
Il permet de reconstruire une nouvelle VM avec la même configuration technique si le modèle, le stockage, les bridges et les préparatifs externes sont toujours disponibles. Il ne sauvegarde ni les données de l’ancienne VM, ni ses UUID, machine-id, clés hôte SSH ou mots de passe. Ces identités sont traitées par le cycle et ne sont pas à recopier.&lt;br /&gt;
&lt;br /&gt;
Avec vmid: null, le VMID de remplacement peut différer de celui de l’ancienne VM. Le VMID 505 observé pendant la recette n’est pas une réservation permanente.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ne pas lancer cette référence tant que MERCURE3 existe encore.&#039;&#039;&#039; Le clonage refuse un nom déjà présent. Pour tester une deuxième VM en parallèle, définir un autre nom, hostname, des IP distinctes et préparer DNS/OPNsense/Ansible en conséquence.&lt;br /&gt;
&lt;br /&gt;
=== 4.3. Valeurs acceptées ===&lt;br /&gt;
&lt;br /&gt;
* projet.environnement et tags : interne, client, prod. Les tags sont une liste sans doublons ; [] est admis.&lt;br /&gt;
* CPU, mémoire et taille du disque : entiers strictement positifs ; mémoire minimale inférieure ou égale à la maximale.&lt;br /&gt;
* Booléens : utiliser true ou false sans guillemets.&lt;br /&gt;
* Interfaces Proxmox : net suivi de chiffres ; interfaces invitées : ens suivi de chiffres.&lt;br /&gt;
* Adresses d’interfaces : IPv4/CIDR. Loopback : IPv4/32. Passerelle et DNS : IPv4 sans préfixe.&lt;br /&gt;
* Passerelle : interface déclarée et adresse appartenant à son sous-réseau, distincte des adresses de la VM.&lt;br /&gt;
* Hostname : nom DNS en minuscules.&lt;br /&gt;
* Serveur, bridge et stockage : valeurs adaptées à l’infrastructure ; aucune liste fermée inventée.&lt;br /&gt;
&lt;br /&gt;
Les clés inconnues ou répétées sont refusées. Ne pas ajouter de sections applicatives avant l’évolution coordonnée du schéma et des scripts. Ne pas utiliser [à renseigner] : les crochets créent une liste YAML.&lt;br /&gt;
&lt;br /&gt;
== 5. Préparer et valider le YAML ==&lt;br /&gt;
&lt;br /&gt;
Sur Saturne3, se placer dans le lot de recette :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5.1. Vérifier un fichier existant sans le modifier ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml /etc/ajlsm/deploy/projets/mercure3.yaml --check&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le message de succès signifie que les valeurs et leur cohérence locale sont conformes. Il ne certifie pas la préparation des services externes.&lt;br /&gt;
&lt;br /&gt;
Voici un exemple : &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;projet:&lt;br /&gt;
  code: mercure3&lt;br /&gt;
  nom: MERCURE3&lt;br /&gt;
  environnement: interne&lt;br /&gt;
&lt;br /&gt;
proxmox:&lt;br /&gt;
  serveur: Saturne3&lt;br /&gt;
  template_vmid: 506&lt;br /&gt;
  vmid: null&lt;br /&gt;
  nom_vm: MERCURE3&lt;br /&gt;
&lt;br /&gt;
  cpu:&lt;br /&gt;
    sockets: 1&lt;br /&gt;
    cores: 8&lt;br /&gt;
&lt;br /&gt;
  memoire:&lt;br /&gt;
    maximale_mib: 24576&lt;br /&gt;
    minimale_mib: 16384&lt;br /&gt;
&lt;br /&gt;
  disque_systeme:&lt;br /&gt;
    stockage: local-zfs&lt;br /&gt;
    taille_gib: 100&lt;br /&gt;
    etendre_volume_racine: true&lt;br /&gt;
&lt;br /&gt;
  demarrage_auto: true&lt;br /&gt;
&lt;br /&gt;
  tags:&lt;br /&gt;
    - interne&lt;br /&gt;
&lt;br /&gt;
systeme:&lt;br /&gt;
  hostname: mercure3.ajlsm.com&lt;br /&gt;
&lt;br /&gt;
reseau:&lt;br /&gt;
  interfaces:&lt;br /&gt;
    - nom: net0&lt;br /&gt;
      bridge: vmbr2&lt;br /&gt;
      systeme: ens18&lt;br /&gt;
      ipv4: 10.0.0.43/24&lt;br /&gt;
&lt;br /&gt;
    - nom: net1&lt;br /&gt;
      bridge: vmbr1&lt;br /&gt;
      systeme: ens19&lt;br /&gt;
      ipv4: 192.168.123.27/24&lt;br /&gt;
&lt;br /&gt;
  loopback:&lt;br /&gt;
    ipv4: 51.83.117.113/32&lt;br /&gt;
&lt;br /&gt;
  passerelle:&lt;br /&gt;
    ipv4: 10.0.0.4&lt;br /&gt;
    interface: ens18&lt;br /&gt;
&lt;br /&gt;
  dns:&lt;br /&gt;
    - 10.0.0.4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5.2. Compléter le modèle vierge ===&lt;br /&gt;
&lt;br /&gt;
Après extraction du présent lot documentaire :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml \&lt;br /&gt;
  /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-documentation/projet-vierge.yaml \&lt;br /&gt;
  --output /root/ajlsm-deploy/recettes/20261016/nouveau-projet.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Toutes les valeurs obligatoires seront demandées. Pour saisir de nouveau le projet MERCURE3, consulter mercure3-reference.yaml comme fiche de paramètres, sans lancer de déploiement.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;# Préconfiguration AJLSM vierge : aucune valeur d’infrastructure préremplie.&lt;br /&gt;
# Compléter avec ajlsm-deploy-yaml ; ne pas déployer ce modèle tel quel.&lt;br /&gt;
# null = champ à renseigner, SAUF proxmox.vmid où null = attribution automatique.&lt;br /&gt;
# Les crochets [à renseigner] sont interdits : ils représenteraient une liste YAML.&lt;br /&gt;
# Deux interfaces sont proposées : adapter leur nombre avant la saisie.&lt;br /&gt;
projet:&lt;br /&gt;
  code: null  # Obligatoire : minuscules/chiffres, tiret et souligné ; ex. mercure3.&lt;br /&gt;
  nom: null  # Obligatoire : nom lisible du projet.&lt;br /&gt;
  environnement: null  # Liste fermée : interne, client, prod.&lt;br /&gt;
&lt;br /&gt;
proxmox:&lt;br /&gt;
  serveur: null  # Obligatoire : nom du nœud Proxmox, ex. Saturne3.&lt;br /&gt;
  template_vmid: null  # Obligatoire : entier positif, VM modèle existante et arrêtée.&lt;br /&gt;
  vmid: null  # Automatique ; sinon entier positif différent de template_vmid.&lt;br /&gt;
  nom_vm: null  # Obligatoire : nom de VM, lettres/chiffres/point/tiret.&lt;br /&gt;
  cpu:&lt;br /&gt;
    sockets: null  # Obligatoire : entier positif.&lt;br /&gt;
    cores: null  # Obligatoire : entier positif ; vCPU = sockets × cores.&lt;br /&gt;
  memoire:&lt;br /&gt;
    maximale_mib: null  # Obligatoire : entier positif, en Mio.&lt;br /&gt;
    minimale_mib: null  # Obligatoire : entier positif, inférieur ou égal au maximum.&lt;br /&gt;
  disque_systeme:&lt;br /&gt;
    stockage: null  # Obligatoire : identifiant de stockage Proxmox existant.&lt;br /&gt;
    taille_gib: null  # Obligatoire : entier positif en Gio ; aucune réduction de disque.&lt;br /&gt;
    etendre_volume_racine: null  # Obligatoire : true ou false ; active la phase racine.&lt;br /&gt;
  demarrage_auto: null  # Obligatoire : true ou false ; appliqué à l’activation réseau.&lt;br /&gt;
  tags: null  # Obligatoire : liste ; interne/client/prod uniquement, sans doublons ; [] admis.&lt;br /&gt;
&lt;br /&gt;
systeme:&lt;br /&gt;
  hostname: null  # Obligatoire : nom DNS en minuscules ; vérifier sa déclaration en amont.&lt;br /&gt;
&lt;br /&gt;
reseau:&lt;br /&gt;
  interfaces:&lt;br /&gt;
    - nom: null  # Obligatoire : net suivi de chiffres, conforme à la VM modèle.&lt;br /&gt;
      bridge: null  # Obligatoire : bridge existant, au plus 15 caractères.&lt;br /&gt;
      systeme: null  # Obligatoire : ens suivi de chiffres, conforme au modèle actuel.&lt;br /&gt;
      ipv4: null  # Obligatoire : IPv4/CIDR, ex. 10.0.0.43/24 ; adresse unique.&lt;br /&gt;
    - nom: null&lt;br /&gt;
      bridge: null&lt;br /&gt;
      systeme: null&lt;br /&gt;
      ipv4: null&lt;br /&gt;
  loopback:&lt;br /&gt;
    ipv4: null  # Obligatoire : IPv4 avec préfixe /32, distincte des interfaces.&lt;br /&gt;
  passerelle:&lt;br /&gt;
    ipv4: null  # Obligatoire : IPv4 seule, dans le sous-réseau de son interface.&lt;br /&gt;
    interface: null  # Obligatoire : un des noms systeme déclarés ci-dessus.&lt;br /&gt;
  dns: null  # Obligatoire : liste non vide d’IPv4 sans préfixe, ex. [10.0.0.4].&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5.3. Créer sans modèle ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml /root/ajlsm-deploy/recettes/20261016/nouveau-projet.yaml --new&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette commande est une alternative à la précédente : le chemin doit être inexistant. L’assistant pose les questions, y compris le nombre d’interfaces, sans reprendre implicitement les valeurs de MERCURE3.&lt;br /&gt;
&lt;br /&gt;
=== 5.4. Revoir un projet renseigné ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml /etc/ajlsm/deploy/projets/mercure3.yaml --review \&lt;br /&gt;
  --output /root/ajlsm-deploy/recettes/20261016/mercure3-relecture.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Entrée conserve une valeur existante valide.&lt;br /&gt;
* ANNULER, Ctrl-C ou fin d’entrée abandonnent sans enregistrer.&lt;br /&gt;
* Tags et DNS sont saisis séparés par des virgules ; [] ou aucun signifie tags vides.&lt;br /&gt;
* Saisir auto ou null pour un VMID automatique.&lt;br /&gt;
* Après une incohérence, donner le chemin du champ à corriger ; ? affiche les chemins.&lt;br /&gt;
* Le résumé complet est présenté avant confirmation OUI/NON d’enregistrement.&lt;br /&gt;
&lt;br /&gt;
L’original reste intact, avec ses commentaires. La copie est réécrite en YAML, sans reprise des commentaires. Aucun fichier existant n’est écrasé. Si une destination existe, choisir un nouveau nom avec --output.&lt;br /&gt;
&lt;br /&gt;
=== 5.5. Préparatifs externes ===&lt;br /&gt;
&lt;br /&gt;
Avant une création, vérifier séparément la réservation des IP, les déclarations DNS, les règles/routes/NAT nécessaires dans OPNsense et l’inventaire ou les préparatifs Ansible. Ne pas inscrire de mots de passe dans le YAML ; conserver les secrets dans le dispositif prévu pour leur gestion.&lt;br /&gt;
&lt;br /&gt;
L’assistant actuel ne vérifie pas automatiquement ces services et ne marque pas un projet « prêt à déployer » sur cette seule base. Leur intégration reste à réaliser.&lt;br /&gt;
&lt;br /&gt;
Le contrôle Proxmox autonome examine notamment le modèle, ses ressources, le stockage et les bridges. Il concerne une nouvelle création et peut refuser un projet déjà déployé :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-check /chemin/vers/projet.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 6. Afficher le plan puis lancer le cycle ==&lt;br /&gt;
&lt;br /&gt;
=== 6.1. Plan sans exécution ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /chemin/vers/projet.yaml --plan&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le plan valide le YAML et affiche les commandes, sans exécuter les phases ni vérifier l’infrastructure. Il doit contenir les 11 étapes, toutes dans le dossier de recette.&lt;br /&gt;
&lt;br /&gt;
=== 6.2. Cycle réel pour une nouvelle VM ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /chemin/vers/projet.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le lanceur exécute les phases réelles, sans simulation automatique. Il attend seulement les confirmations, les saisies nécessaires et la fin de chaque commande. Il s’arrête sur refus ou erreur. Il ne répond pas à la place de l’administrateur et ne capture pas les mots de passe.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! N° !! Étape !! Commande réelle !! Simulation facultative&lt;br /&gt;
|-&lt;br /&gt;
| 1 || Clonage || --clone || --dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Ressources || --configure-resources || --resources-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Premier démarrage isolé || --first-boot-apply || --first-boot-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Extension partition/LVM/ext4 || --root-grow-apply || --root-grow-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Identité système || --system-apply || --system-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Préparation Netplan || --network-apply || --network-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Activation réseau || --network-enable || --network-enable-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Audit SSH || --ssh-audit || Aucune option dédiée&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Sécurisation SSH || --ssh-secure || Aucune option dédiée&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Mot de passe ajlsm || --password-ajlsm || Aucune option dédiée&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Certificat TLS interne || --tls-apply || Aucune option dédiée&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
L’extension racine est indispensable quand etendre_volume_racine vaut true. Agrandir le disque Proxmox ne suffit pas : la partition, le PV LVM, le LV et ext4 doivent aussi être étendus. Cette phase doit figurer après le premier démarrage, avant la personnalisation système. Avec false, la phase annonce sa désactivation.&lt;br /&gt;
&lt;br /&gt;
Le démarrage et la personnalisation se font réseau isolé. Netplan est préparé avant activation des liens. La phase d’activation contrôle le réseau et applique demarrage_auto.&lt;br /&gt;
&lt;br /&gt;
Le certificat TLS interne ne constitue pas, à lui seul, une configuration des applications du projet ou un certificat publiquement reconnu.&lt;br /&gt;
&lt;br /&gt;
=== 6.3. Mode manuel ===&lt;br /&gt;
&lt;br /&gt;
Chaque phase peut être lancée séparément avec ./ajlsm-deploy suivi du YAML et de son option. Après succès, le lot courant affiche deux lignes pour l’étape suivante : Simulation et Exécution. Si la simulation n’existe pas, il le signale. Aucune suggestion n’est exécutée automatiquement.&lt;br /&gt;
&lt;br /&gt;
Les simulations peuvent consulter l’invité et émettre des sondes ARP selon la phase : elles ne sont pas toutes des contrôles hors ligne. L’absence de réponse ARP ne remplace pas la réservation des adresses dans l’inventaire réseau.&lt;br /&gt;
&lt;br /&gt;
== 7. Erreur, annulation et reprise ==&lt;br /&gt;
&lt;br /&gt;
Conserver la sortie complète et diagnostiquer la phase fautive avant de reprendre. Une phase peut être partiellement effectuée ; le lanceur n’effectue ni suppression de VM ni restauration globale automatique.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /chemin/vers/projet.yaml --from extension-racine&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--from inclut l’étape indiquée et saute les précédentes à la demande de l’administrateur. Il ne certifie pas leur état. Les contrôles propres aux phases restent actifs. Le lanceur ne possède pas de journal persistant global de progression.&lt;br /&gt;
&lt;br /&gt;
Ne pas relancer le cycle depuis le clonage sur une VM existante pour terminer une étape. Ne pas relancer des étapes déjà terminées uniquement parce qu’une commande manuelle les suggère. Les suggestions suivent l’ordre théorique et ne constituent pas un inventaire de l’état de la VM.&lt;br /&gt;
&lt;br /&gt;
Codes de sortie : 0 succès, 1 annulation, 2 erreur. Le lanceur normalise les autres codes d’échec de ses sous-processus en erreur et ne poursuit pas.&lt;br /&gt;
&lt;br /&gt;
== 8. Vérifications finales ==&lt;br /&gt;
&lt;br /&gt;
Sur Saturne3, avec le VMID réellement annoncé au clonage :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
qm list&lt;br /&gt;
qm status VMID&lt;br /&gt;
qm config VMID&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remplacer VMID par l’identifiant vérifié. Contrôler le nom, les CPU, la RAM, le disque, les liens réseau et onboot selon le YAML.&lt;br /&gt;
&lt;br /&gt;
Depuis Saturne3, ouvrir la connexion et attendre l’invite de la VM :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh ajlsm@10.0.0.43&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dans MERCURE3, saisir sudo -i, attendre l’authentification et l’invite root, puis :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
hostname&lt;br /&gt;
lsblk&lt;br /&gt;
df -hT /&lt;br /&gt;
ip -br addr&lt;br /&gt;
ip route&lt;br /&gt;
resolvectl status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat vérifié pendant la recette : hostname mercure3.ajlsm.com, racine ext4 97 Gio. Les tailles disponibles évoluent avec l’utilisation. Les commandes SSH et TLS du cycle vérifient leurs propres résultats ; compléter par les tests d’accès attendus dans le réseau cible.&lt;br /&gt;
&lt;br /&gt;
== 9. Reconstruire MERCURE3 ultérieurement ==&lt;br /&gt;
&lt;br /&gt;
# Conserver le fichier mercure3-reference.yaml, le lot de scripts validé et l’identification du modèle utilisé.&lt;br /&gt;
# Comparer la référence au YAML effectivement utilisé avant reconstruction ; actualiser les changements d’infrastructure.&lt;br /&gt;
# Identifier et sauvegarder les données à conserver : le YAML n’est pas une sauvegarde de VM.&lt;br /&gt;
# Vérifier explicitement l’identité de l’ancienne VM et traiter séparément son arrêt et sa suppression volontaire. Le cycle ne détruit jamais automatiquement une VM existante.&lt;br /&gt;
# Contrôler DNS, OPNsense, Ansible et les réservations d’IP. Ne pas laisser deux VM actives avec les mêmes adresses.&lt;br /&gt;
# Valider la référence avec --check, afficher le --plan, puis lancer le cycle sur la référence après libération de la cible.&lt;br /&gt;
# Relever le nouveau VMID et effectuer les vérifications finales.&lt;br /&gt;
&lt;br /&gt;
On retrouve ainsi les paramètres de la VM, sans chercher à reproduire ses anciennes identités techniques.&lt;br /&gt;
&lt;br /&gt;
== 10. Protections et détails techniques ==&lt;br /&gt;
&lt;br /&gt;
=== 10.1. Isolation, identité et journal de personnalisation ===&lt;br /&gt;
&lt;br /&gt;
Le clone est arrêté après création, avec onboot désactivé et les interfaces isolées. Le premier démarrage s’effectue dans cet état d’isolation. Les phases système et réseau vérifient l’identité de la cible et l’UUID attendu selon leurs contrôles propres.&lt;br /&gt;
&lt;br /&gt;
La personnalisation système conserve dans l’invité :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/var/lib/ajlsm/system-personalisation/state.json&lt;br /&gt;
/var/lib/ajlsm/system-personalisation/backup/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce journal décrit la transaction d’identité, pas l’ensemble du cycle. Ne pas le supprimer pour forcer une nouvelle exécution. Après interruption, conserver les sauvegardes et examiner l’état réel avant reprise.&lt;br /&gt;
&lt;br /&gt;
La VM 515 est signalée comme hors périmètre par la documentation historique. Elle ne fait pas partie de la recette MERCURE3 et ne doit pas être ciblée par cette procédure.&lt;br /&gt;
&lt;br /&gt;
=== 10.2. Audit SSH : lecture dans la VM, écriture possible sur Saturne3 ===&lt;br /&gt;
&lt;br /&gt;
La phase --ssh-audit commence par synchroniser l’identité SSH :&lt;br /&gt;
# Lire la clé publique /etc/ssh/ssh_host_ed25519_key.pub dans la VM via l’agent QEMU.&lt;br /&gt;
# Valider le format ED25519 et sa structure binaire attendue.&lt;br /&gt;
# Lire indépendamment la clé exposée sur le réseau avec ssh-keyscan -T 8 -t ed25519.&lt;br /&gt;
# Comparer les clés : une divergence, une absence ou un format invalide provoque un refus.&lt;br /&gt;
# Après concordance seulement, sauvegarder /root/.ssh/known_hosts sur Saturne3, travailler sur une copie et remplacer le fichier avec la nouvelle entrée vérifiée pour l’IP cible.&lt;br /&gt;
# Contrôler les connexions par clé, les clés autorisées, sudo et l’état du compte ajlsm.&lt;br /&gt;
&lt;br /&gt;
Les autres entrées d’hôtes sont conservées ; le traitement retire aussi les anciennes entrées hachées correspondant à l’IP cible. Les sauvegardes utilisent le préfixe known_hosts.ajlsm-backup. dans /root/.ssh/.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;L’audit n’est donc pas entièrement sans écriture :&#039;&#039;&#039; ses lectures dans la VM sont accompagnées d’une mise à jour possible de known_hosts sur Saturne3. Ne jamais contourner une divergence en effaçant aveuglément known_hosts.&lt;br /&gt;
&lt;br /&gt;
=== 10.3. Sécurisation SSH et mot de passe ===&lt;br /&gt;
&lt;br /&gt;
--ssh-secure effectue un audit préalable, prépare un fichier SSH dédié, vérifie la syntaxe et les valeurs effectives, puis recharge SSH. Il désactive l’authentification SSH par mot de passe et conserve root par clé. Les connexions root et ajlsm par clé sont revérifiées par le code reçu.&lt;br /&gt;
&lt;br /&gt;
Le mot de passe local ajlsm reste utile pour sudo. --password-ajlsm utilise un terminal interactif et lance passwd dans la VM, avec sa double saisie masquée. Le secret n’est pas inscrit dans le YAML ni dans la ligne de commande. La procédure historique prévoit un report manuel dans le registre ODS d’administration ; appliquer les règles internes de gestion des secrets. Ne pas joindre ce registre à une documentation publique.&lt;br /&gt;
&lt;br /&gt;
=== 10.4. Certificat TLS interne et Apache ===&lt;br /&gt;
&lt;br /&gt;
--tls-apply lit le certificat /etc/ssl/ajlsm/server.crt. Si le CN et le SAN correspondent déjà au hostname attendu, la phase termine sans réinitialisation. Sinon, après confirmation, elle appelle /usr/local/sbin/ajlsm-init-tls.sh &#039;&#039;&#039;dans la VM&#039;&#039;&#039;. Ce dernier script doit être présent dans le modèle ; son contenu n’était pas inclus dans l’archive des scripts de déploiement reçue.&lt;br /&gt;
&lt;br /&gt;
Après une initialisation réussie, le module contrôle le certificat, apache2ctl configtest et systemctl is-active apache2. Ce contrôle technique d’Apache ne constitue pas une recette des VirtualHosts et des applications du projet.&lt;br /&gt;
&lt;br /&gt;
La documentation historique désigne /home/ajlsm/README, hérité de TEMPLATE3, comme README applicatif Pleade/Drupal. Le conserver séparément du README-ajlsm-deploy de l’outil de déploiement ; ne pas remplacer l’un par l’autre.&lt;br /&gt;
&lt;br /&gt;
=== 10.5. Attente réseau au premier démarrage ===&lt;br /&gt;
&lt;br /&gt;
La recette du 15 octobre signalait environ 60 secondes d’attente dans systemd-networkd-wait-online lorsque les interfaces étaient isolées. Ce constat historique n’a pas empêché l’agent QEMU ni ajlsm-clone-init de répondre. Une optimisation éventuelle du modèle reste distincte du déploiement ; ne pas désactiver le service sans vérifier ses dépendances.&lt;br /&gt;
&lt;br /&gt;
== 11. Maintenance, sauvegardes et manuel ==&lt;br /&gt;
&lt;br /&gt;
=== 11.1. Identifier les fichiers réellement exécutés ===&lt;br /&gt;
&lt;br /&gt;
La recette du 16 octobre utilise le dossier /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/. Elle ne démontre pas une mise à jour globale de /usr/local/sbin/. Toujours distinguer le lot validé et les programmes installés.&lt;br /&gt;
&lt;br /&gt;
Dans le dossier de recette :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy --help&lt;br /&gt;
./ajlsm-deploy-cycle --help&lt;br /&gt;
./ajlsm-deploy-yaml --help&lt;br /&gt;
python3 -m py_compile ajlsm-deploy ajlsm-deploy-check ajlsm-deploy-resources ajlsm-deploy-cycle ajlsm-deploy-yaml ajlsm_deploy_common.py ajlsm_deploy_rootgrow.py ajlsm_deploy_postconfig.py&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Une compilation vérifie la syntaxe, pas le bon déroulement d’une phase ni les prérequis serveur.&lt;br /&gt;
&lt;br /&gt;
=== 11.2. Sauvegarder et restaurer un lot cohérent ===&lt;br /&gt;
&lt;br /&gt;
Conserver ensemble programmes, modules et configuration de référence. Sauvegarder le lot complet avant une installation ou une correction. Exemple sur Saturne3 :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
tar -czf &amp;quot;/root/ajlsm-deploy/archives/lot-recette-$(date +%Y%m%d-%H%M%S).tar.gz&amp;quot; \&lt;br /&gt;
  -C /root/ajlsm-deploy/recettes/20261016 ajlsm-deploy-cycle&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Une restauration doit porter sur un ensemble compatible. Ne pas réinstaller uniquement ajlsm-deploy.bak-20261015 : ce fichier peut précéder les modules et phases nécessaires. L’ancienne sauvegarde et les répertoires de revue sont des références historiques à inventorier avant nettoyage.&lt;br /&gt;
&lt;br /&gt;
Ne pas supprimer INSTRUCTIONS-TEST.txt ou d’autres fichiers de /root/ajlsm-deploy-review/ sur la seule base de l’ancienne page. Leur archivage et le nettoyage ne font pas partie de cette mise à jour documentaire.&lt;br /&gt;
&lt;br /&gt;
=== 11.3. Page man ===&lt;br /&gt;
&lt;br /&gt;
La page du 15 octobre indique un manuel installé en /usr/local/man/man8/ajlsm-deploy.8 et une sauvegarde hors man8 dans /root/ajlsm-deploy-review/sauvegardes-man/. Ce sont des informations historiques, dont l’état actuel n’a pas été vérifié pendant la recette du 16 octobre.&lt;br /&gt;
&lt;br /&gt;
Pour identifier la page disponible sur Saturne3 :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man -w ajlsm-deploy&lt;br /&gt;
man 8 ajlsm-deploy&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Une page absente ne signifie pas que le script est absent : --help est l’aide intégrée de l’exécutable. Le manuel installé doit être réconcilié avec le cycle et l’assistant avant d’être considéré comme référence de cette version. En attendant, le présent guide et l’aide des fichiers du lot de recette décrivent le fonctionnement courant.&lt;br /&gt;
&lt;br /&gt;
== 12. État des validations et limites ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Date / source !! Vérification !! Portée&lt;br /&gt;
|-&lt;br /&gt;
| 15/10/2026, page historique || Déploiements initiaux jusqu’à l’activation réseau || Résultats historiques conservés ; ne décrivent pas à eux seuls le cycle actuel&lt;br /&gt;
|-&lt;br /&gt;
| 15/10/2026, page historique || Comparaison ED25519, clés divergentes ou malformées, préservation de known_hosts || Tests isolés rapportés dans la documentation reçue, non rejoués lors de cette consolidation&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, tests locaux du lot cycle || Ordre des 11 étapes, arrêt sur refus/erreur, reprise et suggestions || 8 tests réussis, incluant des sous-cas ; sous-processus des phases simulés&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, sorties Saturne3 transmises || Cycle technique complet sur un nouveau clone MERCURE3 || Terminé sans erreur signalée, extension racine incluse&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, sorties invitées transmises || SSH ajlsm, sudo, hostname et racine ext4 || Confirmés ; mercure3.ajlsm.com et 97 Gio pour /&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, tests locaux assistant || Création, correction, copie, validation et annulation || 14 tests réussis, saisies simulées&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, sortie Saturne3 transmise || Assistant --check sur mercure3.yaml || Valeurs YAML valides ; aucune écriture ni validation externe&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, vérification locale des modèles || Modèle vierge complété par l’assistant || Paramètres identiques à la référence MERCURE3 ; original intact&lt;br /&gt;
|-&lt;br /&gt;
| À réaliser || Essai réel du mécanisme de repli après échec d’activation réseau || Non confirmé ; le succès du parcours nominal ne valide pas ce scénario&lt;br /&gt;
|-&lt;br /&gt;
| À réaliser || Vérifications automatiques DNS, OPNsense, Ansible et recette applicative || Hors périmètre actuel&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le message de fin du cycle signifie que ses phases ont retourné un succès. Il ne vaut pas validation des applications ni détection de toutes les défaillances possibles. Conserver les vérifications finales et les limites propres aux phases.&lt;br /&gt;
&lt;br /&gt;
== 13. Réconciliation avec la page du 15 octobre ==&lt;br /&gt;
&lt;br /&gt;
L’original reçu est conservé intégralement dans historique/guide-20261015.mediawiki. Il sert de trace, pas de seconde procédure opérationnelle concurrente.&lt;br /&gt;
&lt;br /&gt;
Le présent document remplace les indications opérationnelles anciennes :&lt;br /&gt;
* confirmations CLONER/APPLIQUER/DEMARRER remplacées par OUI/NON ;&lt;br /&gt;
* parcours manuel seul remplacé par le choix entre mode manuel et cycle interactif ;&lt;br /&gt;
* liste des étapes incluant l’extension racine, SSH, mot de passe et TLS ;&lt;br /&gt;
* extension racine et cycle complet désormais validés sur la recette du 16 octobre ;&lt;br /&gt;
* suggestions manuelles affichant les deux commandes disponibles, sans oublier l’extension racine ;&lt;br /&gt;
* création et relecture du YAML par l’assistant, sans écraser l’original ;&lt;br /&gt;
* ajout du modèle vierge et de la référence MERCURE3 renseignée ;&lt;br /&gt;
* séparation explicite des scripts installés, du lot de recette, du manuel historique et de la future installation.&lt;br /&gt;
&lt;br /&gt;
Les détails encore utiles de l’ancienne page sur l’isolation, les transactions, ED25519, les sauvegardes, le README applicatif et les limites de validation sont repris ci-dessus. Une nouvelle mise à jour fonctionnelle doit modifier cette procédure directement plutôt que superposer une nouvelle section corrective à une ancienne procédure contradictoire.&lt;br /&gt;
&lt;br /&gt;
== 14. Suites prévues ==&lt;br /&gt;
&lt;br /&gt;
Prévoir les paramètres NFS, sites Apache2, Pleade, Drupal et Matomo dans le même YAML lorsque leurs exigences seront définies. Modifier ensemble le schéma, l’assistant, les modèles, les précontrôles, les phases et leur documentation. Documenter les références aux secrets plutôt que leurs valeurs.&lt;br /&gt;
&lt;br /&gt;
L’intégration des contrôles DNS, OPNsense et Ansible précédera une déclaration automatisée de disponibilité du projet. Le modèle actuel ne contient pas encore ces nouvelles sections.&lt;br /&gt;
&lt;br /&gt;
[[Catégorie:Infrastructure]]&lt;br /&gt;
[[Catégorie:Proxmox]]&lt;br /&gt;
[[Catégorie:Déploiement]]&lt;br /&gt;
[[Catégorie:AJLSM]]&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=D%C3%A9ploiement_technique_d%E2%80%99une_VM_AJLSM&amp;diff=6493</id>
		<title>Déploiement technique d’une VM AJLSM</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=D%C3%A9ploiement_technique_d%E2%80%99une_VM_AJLSM&amp;diff=6493"/>
		<updated>2026-10-16T16:21:09Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : /* 5.1. Vérifier un fichier existant sans le modifier */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= AJLSM-DEPLOY — Déploiement automatisé des VM Proxmox =&lt;br /&gt;
&lt;br /&gt;
Document consolidé au 16 octobre 2026. Cette procédure réunit la page du 15 octobre et la recette actuelle. Elle remplace leurs indications opérationnelles divergentes. L’original du 15 octobre reste archivé séparément.&lt;br /&gt;
&lt;br /&gt;
Référence technique : scripts reçus de Saturne3, puis lot de recette avec lanceur du cycle et assistant YAML.&lt;br /&gt;
&lt;br /&gt;
== 1. Périmètre et résultat de la recette ==&lt;br /&gt;
&lt;br /&gt;
Le cycle technique a été exécuté sur MERCURE3 sans erreur signalée. Les vérifications finales transmises confirment :&lt;br /&gt;
* connexion SSH avec le compte ajlsm ;&lt;br /&gt;
* élévation sudo avec le mot de passe défini pendant le cycle ;&lt;br /&gt;
* hostname mercure3.ajlsm.com ;&lt;br /&gt;
* volume racine ext4 de 97 Gio, dont 85 Gio disponibles lors du contrôle.&lt;br /&gt;
&lt;br /&gt;
Le cycle couvre le clonage, les ressources, l’initialisation du clone, l’extension de la racine, l’identité système, le réseau, SSH, le mot de passe et le certificat TLS interne.&lt;br /&gt;
&lt;br /&gt;
NFS, les configurations applicatives Apache2, Pleade, Drupal et Matomo ne font pas encore partie de ce cycle. Certains logiciels peuvent déjà être présents dans le modèle : leur présence ne constitue pas une configuration applicative du projet.&lt;br /&gt;
&lt;br /&gt;
== 2. Où exécuter les commandes ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Machine !! Rôle !! Exemple d’invite&lt;br /&gt;
|-&lt;br /&gt;
| Mac de l’administrateur || Transfert des archives par scp || Invite locale du Mac&lt;br /&gt;
|-&lt;br /&gt;
| Saturne3 || Préparation YAML, scripts Proxmox et cycle || root@Saturne3&lt;br /&gt;
|-&lt;br /&gt;
| MERCURE3 || Vérifications dans la VM || ajlsm@mercure3 ou root@mercure3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les scripts de déploiement sont exécutés sur Saturne3, pas dans MERCURE3.&lt;br /&gt;
Après « ssh ajlsm@10.0.0.43 », attendre l’invite de la VM avant de saisir les commandes suivantes.&lt;br /&gt;
Pour revenir de root@mercure3 à Saturne3 : un exit quitte sudo, puis un second exit ferme SSH.&lt;br /&gt;
&lt;br /&gt;
== 3. Organisation des fichiers ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/root/ajlsm-deploy/&lt;br /&gt;
  archives/                         Archives reçues, conservées comme références&lt;br /&gt;
  recettes/20261016/&lt;br /&gt;
    ajlsm-deploy-cycle/             Lot technique validé et assistant ajouté&lt;br /&gt;
    ajlsm-deploy-assistant/         Distribution de l’assistant et tests&lt;br /&gt;
    ajlsm-deploy-documentation/     Présent guide et modèles YAML&lt;br /&gt;
&lt;br /&gt;
/etc/ajlsm/deploy/projets/mercure3.yaml   Configuration actuellement utilisée&lt;br /&gt;
/usr/local/sbin/                        Scripts installés antérieurement&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le lot de recette contient ajlsm-deploy, ajlsm-deploy-check, ajlsm-deploy-resources, ajlsm-deploy-cycle et les modules ajlsm_deploy_common.py, ajlsm_deploy_rootgrow.py et ajlsm_deploy_postconfig.py. L’assistant ajlsm-deploy-yaml a été ajouté à ce même dossier.&lt;br /&gt;
&lt;br /&gt;
Conserver exécutables et modules ensemble. Utiliser les chemins ./ depuis le dossier de recette pour ne pas appeler une ancienne version de /usr/local/sbin.&lt;br /&gt;
Les anciennes archives « ajlsm-deploy-revise » et « correction-suggestions » ne sont pas la référence courante : elles précèdent les phases supplémentaires reçues dans l’archive serveur.&lt;br /&gt;
&lt;br /&gt;
Prérequis : Python 3.9 ou supérieur, PyYAML 6, outils Proxmox sur le nœud cible et prérequis du modèle AJLSM. Les phases invitées utilisent notamment l’agent QEMU, ajlsm-clone-init, Python, systemd et Netplan. L’extension actuelle cible ext4/LVM sur /dev/sda3, avec un seul PV et un seul LV.&lt;br /&gt;
&lt;br /&gt;
== 4. Les deux fichiers de préconfiguration ==&lt;br /&gt;
&lt;br /&gt;
=== 4.1. projet-vierge.yaml ===&lt;br /&gt;
&lt;br /&gt;
Ce modèle reprend toute la structure actuelle sans valeur opérationnelle préremplie. Chaque champ doit être renseigné. Seul proxmox.vmid peut rester null : il signifie alors attribution automatique.&lt;br /&gt;
&lt;br /&gt;
Le modèle comporte deux interfaces dont les valeurs sont null. Adapter le nombre d’interfaces avant la saisie si nécessaire. Pour déterminer ce nombre par les questions de l’assistant, utiliser plutôt le mode --new.&lt;br /&gt;
&lt;br /&gt;
Un modèle vierge est volontairement refusé par --check. Il ne doit jamais être passé directement au lanceur du cycle.&lt;br /&gt;
&lt;br /&gt;
=== 4.2. mercure3-reference.yaml ===&lt;br /&gt;
&lt;br /&gt;
Ce fichier conserve les valeurs du projet validé : modèle 506 sur Saturne3, nom MERCURE3, 8 vCPU, 24576 Mio de RAM maximale, 16384 Mio minimale, disque 100 Gio, extension racine activée et paramètres réseau du projet.&lt;br /&gt;
&lt;br /&gt;
Il permet de reconstruire une nouvelle VM avec la même configuration technique si le modèle, le stockage, les bridges et les préparatifs externes sont toujours disponibles. Il ne sauvegarde ni les données de l’ancienne VM, ni ses UUID, machine-id, clés hôte SSH ou mots de passe. Ces identités sont traitées par le cycle et ne sont pas à recopier.&lt;br /&gt;
&lt;br /&gt;
Avec vmid: null, le VMID de remplacement peut différer de celui de l’ancienne VM. Le VMID 505 observé pendant la recette n’est pas une réservation permanente.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ne pas lancer cette référence tant que MERCURE3 existe encore.&#039;&#039;&#039; Le clonage refuse un nom déjà présent. Pour tester une deuxième VM en parallèle, définir un autre nom, hostname, des IP distinctes et préparer DNS/OPNsense/Ansible en conséquence.&lt;br /&gt;
&lt;br /&gt;
=== 4.3. Valeurs acceptées ===&lt;br /&gt;
&lt;br /&gt;
* projet.environnement et tags : interne, client, prod. Les tags sont une liste sans doublons ; [] est admis.&lt;br /&gt;
* CPU, mémoire et taille du disque : entiers strictement positifs ; mémoire minimale inférieure ou égale à la maximale.&lt;br /&gt;
* Booléens : utiliser true ou false sans guillemets.&lt;br /&gt;
* Interfaces Proxmox : net suivi de chiffres ; interfaces invitées : ens suivi de chiffres.&lt;br /&gt;
* Adresses d’interfaces : IPv4/CIDR. Loopback : IPv4/32. Passerelle et DNS : IPv4 sans préfixe.&lt;br /&gt;
* Passerelle : interface déclarée et adresse appartenant à son sous-réseau, distincte des adresses de la VM.&lt;br /&gt;
* Hostname : nom DNS en minuscules.&lt;br /&gt;
* Serveur, bridge et stockage : valeurs adaptées à l’infrastructure ; aucune liste fermée inventée.&lt;br /&gt;
&lt;br /&gt;
Les clés inconnues ou répétées sont refusées. Ne pas ajouter de sections applicatives avant l’évolution coordonnée du schéma et des scripts. Ne pas utiliser [à renseigner] : les crochets créent une liste YAML.&lt;br /&gt;
&lt;br /&gt;
== 5. Préparer et valider le YAML ==&lt;br /&gt;
&lt;br /&gt;
Sur Saturne3, se placer dans le lot de recette :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5.1. Vérifier un fichier existant sans le modifier ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml /etc/ajlsm/deploy/projets/mercure3.yaml --check&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le message de succès signifie que les valeurs et leur cohérence locale sont conformes. Il ne certifie pas la préparation des services externes.&lt;br /&gt;
&lt;br /&gt;
Voici un exemple : &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;projet:&lt;br /&gt;
  code: mercure3&lt;br /&gt;
  nom: MERCURE3&lt;br /&gt;
  environnement: interne&lt;br /&gt;
&lt;br /&gt;
proxmox:&lt;br /&gt;
  serveur: Saturne3&lt;br /&gt;
  template_vmid: 506&lt;br /&gt;
  vmid: null&lt;br /&gt;
  nom_vm: MERCURE3&lt;br /&gt;
&lt;br /&gt;
  cpu:&lt;br /&gt;
    sockets: 1&lt;br /&gt;
    cores: 8&lt;br /&gt;
&lt;br /&gt;
  memoire:&lt;br /&gt;
    maximale_mib: 24576&lt;br /&gt;
    minimale_mib: 16384&lt;br /&gt;
&lt;br /&gt;
  disque_systeme:&lt;br /&gt;
    stockage: local-zfs&lt;br /&gt;
    taille_gib: 100&lt;br /&gt;
    etendre_volume_racine: true&lt;br /&gt;
&lt;br /&gt;
  demarrage_auto: true&lt;br /&gt;
&lt;br /&gt;
  tags:&lt;br /&gt;
    - interne&lt;br /&gt;
&lt;br /&gt;
systeme:&lt;br /&gt;
  hostname: mercure3.ajlsm.com&lt;br /&gt;
&lt;br /&gt;
reseau:&lt;br /&gt;
  interfaces:&lt;br /&gt;
    - nom: net0&lt;br /&gt;
      bridge: vmbr2&lt;br /&gt;
      systeme: ens18&lt;br /&gt;
      ipv4: 10.0.0.43/24&lt;br /&gt;
&lt;br /&gt;
    - nom: net1&lt;br /&gt;
      bridge: vmbr1&lt;br /&gt;
      systeme: ens19&lt;br /&gt;
      ipv4: 192.168.123.27/24&lt;br /&gt;
&lt;br /&gt;
  loopback:&lt;br /&gt;
    ipv4: 51.83.117.113/32&lt;br /&gt;
&lt;br /&gt;
  passerelle:&lt;br /&gt;
    ipv4: 10.0.0.4&lt;br /&gt;
    interface: ens18&lt;br /&gt;
&lt;br /&gt;
  dns:&lt;br /&gt;
    - 10.0.0.4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5.2. Compléter le modèle vierge ===&lt;br /&gt;
&lt;br /&gt;
Après extraction du présent lot documentaire :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml \&lt;br /&gt;
  /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-documentation/projet-vierge.yaml \&lt;br /&gt;
  --output /root/ajlsm-deploy/recettes/20261016/nouveau-projet.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Toutes les valeurs obligatoires seront demandées. Pour saisir de nouveau le projet MERCURE3, consulter mercure3-reference.yaml comme fiche de paramètres, sans lancer de déploiement.&lt;br /&gt;
&lt;br /&gt;
=== 5.3. Créer sans modèle ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml /root/ajlsm-deploy/recettes/20261016/nouveau-projet.yaml --new&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette commande est une alternative à la précédente : le chemin doit être inexistant. L’assistant pose les questions, y compris le nombre d’interfaces, sans reprendre implicitement les valeurs de MERCURE3.&lt;br /&gt;
&lt;br /&gt;
=== 5.4. Revoir un projet renseigné ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml /etc/ajlsm/deploy/projets/mercure3.yaml --review \&lt;br /&gt;
  --output /root/ajlsm-deploy/recettes/20261016/mercure3-relecture.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Entrée conserve une valeur existante valide.&lt;br /&gt;
* ANNULER, Ctrl-C ou fin d’entrée abandonnent sans enregistrer.&lt;br /&gt;
* Tags et DNS sont saisis séparés par des virgules ; [] ou aucun signifie tags vides.&lt;br /&gt;
* Saisir auto ou null pour un VMID automatique.&lt;br /&gt;
* Après une incohérence, donner le chemin du champ à corriger ; ? affiche les chemins.&lt;br /&gt;
* Le résumé complet est présenté avant confirmation OUI/NON d’enregistrement.&lt;br /&gt;
&lt;br /&gt;
L’original reste intact, avec ses commentaires. La copie est réécrite en YAML, sans reprise des commentaires. Aucun fichier existant n’est écrasé. Si une destination existe, choisir un nouveau nom avec --output.&lt;br /&gt;
&lt;br /&gt;
=== 5.5. Préparatifs externes ===&lt;br /&gt;
&lt;br /&gt;
Avant une création, vérifier séparément la réservation des IP, les déclarations DNS, les règles/routes/NAT nécessaires dans OPNsense et l’inventaire ou les préparatifs Ansible. Ne pas inscrire de mots de passe dans le YAML ; conserver les secrets dans le dispositif prévu pour leur gestion.&lt;br /&gt;
&lt;br /&gt;
L’assistant actuel ne vérifie pas automatiquement ces services et ne marque pas un projet « prêt à déployer » sur cette seule base. Leur intégration reste à réaliser.&lt;br /&gt;
&lt;br /&gt;
Le contrôle Proxmox autonome examine notamment le modèle, ses ressources, le stockage et les bridges. Il concerne une nouvelle création et peut refuser un projet déjà déployé :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-check /chemin/vers/projet.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 6. Afficher le plan puis lancer le cycle ==&lt;br /&gt;
&lt;br /&gt;
=== 6.1. Plan sans exécution ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /chemin/vers/projet.yaml --plan&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le plan valide le YAML et affiche les commandes, sans exécuter les phases ni vérifier l’infrastructure. Il doit contenir les 11 étapes, toutes dans le dossier de recette.&lt;br /&gt;
&lt;br /&gt;
=== 6.2. Cycle réel pour une nouvelle VM ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /chemin/vers/projet.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le lanceur exécute les phases réelles, sans simulation automatique. Il attend seulement les confirmations, les saisies nécessaires et la fin de chaque commande. Il s’arrête sur refus ou erreur. Il ne répond pas à la place de l’administrateur et ne capture pas les mots de passe.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! N° !! Étape !! Commande réelle !! Simulation facultative&lt;br /&gt;
|-&lt;br /&gt;
| 1 || Clonage || --clone || --dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Ressources || --configure-resources || --resources-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Premier démarrage isolé || --first-boot-apply || --first-boot-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Extension partition/LVM/ext4 || --root-grow-apply || --root-grow-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Identité système || --system-apply || --system-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Préparation Netplan || --network-apply || --network-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Activation réseau || --network-enable || --network-enable-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Audit SSH || --ssh-audit || Aucune option dédiée&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Sécurisation SSH || --ssh-secure || Aucune option dédiée&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Mot de passe ajlsm || --password-ajlsm || Aucune option dédiée&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Certificat TLS interne || --tls-apply || Aucune option dédiée&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
L’extension racine est indispensable quand etendre_volume_racine vaut true. Agrandir le disque Proxmox ne suffit pas : la partition, le PV LVM, le LV et ext4 doivent aussi être étendus. Cette phase doit figurer après le premier démarrage, avant la personnalisation système. Avec false, la phase annonce sa désactivation.&lt;br /&gt;
&lt;br /&gt;
Le démarrage et la personnalisation se font réseau isolé. Netplan est préparé avant activation des liens. La phase d’activation contrôle le réseau et applique demarrage_auto.&lt;br /&gt;
&lt;br /&gt;
Le certificat TLS interne ne constitue pas, à lui seul, une configuration des applications du projet ou un certificat publiquement reconnu.&lt;br /&gt;
&lt;br /&gt;
=== 6.3. Mode manuel ===&lt;br /&gt;
&lt;br /&gt;
Chaque phase peut être lancée séparément avec ./ajlsm-deploy suivi du YAML et de son option. Après succès, le lot courant affiche deux lignes pour l’étape suivante : Simulation et Exécution. Si la simulation n’existe pas, il le signale. Aucune suggestion n’est exécutée automatiquement.&lt;br /&gt;
&lt;br /&gt;
Les simulations peuvent consulter l’invité et émettre des sondes ARP selon la phase : elles ne sont pas toutes des contrôles hors ligne. L’absence de réponse ARP ne remplace pas la réservation des adresses dans l’inventaire réseau.&lt;br /&gt;
&lt;br /&gt;
== 7. Erreur, annulation et reprise ==&lt;br /&gt;
&lt;br /&gt;
Conserver la sortie complète et diagnostiquer la phase fautive avant de reprendre. Une phase peut être partiellement effectuée ; le lanceur n’effectue ni suppression de VM ni restauration globale automatique.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /chemin/vers/projet.yaml --from extension-racine&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--from inclut l’étape indiquée et saute les précédentes à la demande de l’administrateur. Il ne certifie pas leur état. Les contrôles propres aux phases restent actifs. Le lanceur ne possède pas de journal persistant global de progression.&lt;br /&gt;
&lt;br /&gt;
Ne pas relancer le cycle depuis le clonage sur une VM existante pour terminer une étape. Ne pas relancer des étapes déjà terminées uniquement parce qu’une commande manuelle les suggère. Les suggestions suivent l’ordre théorique et ne constituent pas un inventaire de l’état de la VM.&lt;br /&gt;
&lt;br /&gt;
Codes de sortie : 0 succès, 1 annulation, 2 erreur. Le lanceur normalise les autres codes d’échec de ses sous-processus en erreur et ne poursuit pas.&lt;br /&gt;
&lt;br /&gt;
== 8. Vérifications finales ==&lt;br /&gt;
&lt;br /&gt;
Sur Saturne3, avec le VMID réellement annoncé au clonage :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
qm list&lt;br /&gt;
qm status VMID&lt;br /&gt;
qm config VMID&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remplacer VMID par l’identifiant vérifié. Contrôler le nom, les CPU, la RAM, le disque, les liens réseau et onboot selon le YAML.&lt;br /&gt;
&lt;br /&gt;
Depuis Saturne3, ouvrir la connexion et attendre l’invite de la VM :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh ajlsm@10.0.0.43&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dans MERCURE3, saisir sudo -i, attendre l’authentification et l’invite root, puis :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
hostname&lt;br /&gt;
lsblk&lt;br /&gt;
df -hT /&lt;br /&gt;
ip -br addr&lt;br /&gt;
ip route&lt;br /&gt;
resolvectl status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat vérifié pendant la recette : hostname mercure3.ajlsm.com, racine ext4 97 Gio. Les tailles disponibles évoluent avec l’utilisation. Les commandes SSH et TLS du cycle vérifient leurs propres résultats ; compléter par les tests d’accès attendus dans le réseau cible.&lt;br /&gt;
&lt;br /&gt;
== 9. Reconstruire MERCURE3 ultérieurement ==&lt;br /&gt;
&lt;br /&gt;
# Conserver le fichier mercure3-reference.yaml, le lot de scripts validé et l’identification du modèle utilisé.&lt;br /&gt;
# Comparer la référence au YAML effectivement utilisé avant reconstruction ; actualiser les changements d’infrastructure.&lt;br /&gt;
# Identifier et sauvegarder les données à conserver : le YAML n’est pas une sauvegarde de VM.&lt;br /&gt;
# Vérifier explicitement l’identité de l’ancienne VM et traiter séparément son arrêt et sa suppression volontaire. Le cycle ne détruit jamais automatiquement une VM existante.&lt;br /&gt;
# Contrôler DNS, OPNsense, Ansible et les réservations d’IP. Ne pas laisser deux VM actives avec les mêmes adresses.&lt;br /&gt;
# Valider la référence avec --check, afficher le --plan, puis lancer le cycle sur la référence après libération de la cible.&lt;br /&gt;
# Relever le nouveau VMID et effectuer les vérifications finales.&lt;br /&gt;
&lt;br /&gt;
On retrouve ainsi les paramètres de la VM, sans chercher à reproduire ses anciennes identités techniques.&lt;br /&gt;
&lt;br /&gt;
== 10. Protections et détails techniques ==&lt;br /&gt;
&lt;br /&gt;
=== 10.1. Isolation, identité et journal de personnalisation ===&lt;br /&gt;
&lt;br /&gt;
Le clone est arrêté après création, avec onboot désactivé et les interfaces isolées. Le premier démarrage s’effectue dans cet état d’isolation. Les phases système et réseau vérifient l’identité de la cible et l’UUID attendu selon leurs contrôles propres.&lt;br /&gt;
&lt;br /&gt;
La personnalisation système conserve dans l’invité :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/var/lib/ajlsm/system-personalisation/state.json&lt;br /&gt;
/var/lib/ajlsm/system-personalisation/backup/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce journal décrit la transaction d’identité, pas l’ensemble du cycle. Ne pas le supprimer pour forcer une nouvelle exécution. Après interruption, conserver les sauvegardes et examiner l’état réel avant reprise.&lt;br /&gt;
&lt;br /&gt;
La VM 515 est signalée comme hors périmètre par la documentation historique. Elle ne fait pas partie de la recette MERCURE3 et ne doit pas être ciblée par cette procédure.&lt;br /&gt;
&lt;br /&gt;
=== 10.2. Audit SSH : lecture dans la VM, écriture possible sur Saturne3 ===&lt;br /&gt;
&lt;br /&gt;
La phase --ssh-audit commence par synchroniser l’identité SSH :&lt;br /&gt;
# Lire la clé publique /etc/ssh/ssh_host_ed25519_key.pub dans la VM via l’agent QEMU.&lt;br /&gt;
# Valider le format ED25519 et sa structure binaire attendue.&lt;br /&gt;
# Lire indépendamment la clé exposée sur le réseau avec ssh-keyscan -T 8 -t ed25519.&lt;br /&gt;
# Comparer les clés : une divergence, une absence ou un format invalide provoque un refus.&lt;br /&gt;
# Après concordance seulement, sauvegarder /root/.ssh/known_hosts sur Saturne3, travailler sur une copie et remplacer le fichier avec la nouvelle entrée vérifiée pour l’IP cible.&lt;br /&gt;
# Contrôler les connexions par clé, les clés autorisées, sudo et l’état du compte ajlsm.&lt;br /&gt;
&lt;br /&gt;
Les autres entrées d’hôtes sont conservées ; le traitement retire aussi les anciennes entrées hachées correspondant à l’IP cible. Les sauvegardes utilisent le préfixe known_hosts.ajlsm-backup. dans /root/.ssh/.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;L’audit n’est donc pas entièrement sans écriture :&#039;&#039;&#039; ses lectures dans la VM sont accompagnées d’une mise à jour possible de known_hosts sur Saturne3. Ne jamais contourner une divergence en effaçant aveuglément known_hosts.&lt;br /&gt;
&lt;br /&gt;
=== 10.3. Sécurisation SSH et mot de passe ===&lt;br /&gt;
&lt;br /&gt;
--ssh-secure effectue un audit préalable, prépare un fichier SSH dédié, vérifie la syntaxe et les valeurs effectives, puis recharge SSH. Il désactive l’authentification SSH par mot de passe et conserve root par clé. Les connexions root et ajlsm par clé sont revérifiées par le code reçu.&lt;br /&gt;
&lt;br /&gt;
Le mot de passe local ajlsm reste utile pour sudo. --password-ajlsm utilise un terminal interactif et lance passwd dans la VM, avec sa double saisie masquée. Le secret n’est pas inscrit dans le YAML ni dans la ligne de commande. La procédure historique prévoit un report manuel dans le registre ODS d’administration ; appliquer les règles internes de gestion des secrets. Ne pas joindre ce registre à une documentation publique.&lt;br /&gt;
&lt;br /&gt;
=== 10.4. Certificat TLS interne et Apache ===&lt;br /&gt;
&lt;br /&gt;
--tls-apply lit le certificat /etc/ssl/ajlsm/server.crt. Si le CN et le SAN correspondent déjà au hostname attendu, la phase termine sans réinitialisation. Sinon, après confirmation, elle appelle /usr/local/sbin/ajlsm-init-tls.sh &#039;&#039;&#039;dans la VM&#039;&#039;&#039;. Ce dernier script doit être présent dans le modèle ; son contenu n’était pas inclus dans l’archive des scripts de déploiement reçue.&lt;br /&gt;
&lt;br /&gt;
Après une initialisation réussie, le module contrôle le certificat, apache2ctl configtest et systemctl is-active apache2. Ce contrôle technique d’Apache ne constitue pas une recette des VirtualHosts et des applications du projet.&lt;br /&gt;
&lt;br /&gt;
La documentation historique désigne /home/ajlsm/README, hérité de TEMPLATE3, comme README applicatif Pleade/Drupal. Le conserver séparément du README-ajlsm-deploy de l’outil de déploiement ; ne pas remplacer l’un par l’autre.&lt;br /&gt;
&lt;br /&gt;
=== 10.5. Attente réseau au premier démarrage ===&lt;br /&gt;
&lt;br /&gt;
La recette du 15 octobre signalait environ 60 secondes d’attente dans systemd-networkd-wait-online lorsque les interfaces étaient isolées. Ce constat historique n’a pas empêché l’agent QEMU ni ajlsm-clone-init de répondre. Une optimisation éventuelle du modèle reste distincte du déploiement ; ne pas désactiver le service sans vérifier ses dépendances.&lt;br /&gt;
&lt;br /&gt;
== 11. Maintenance, sauvegardes et manuel ==&lt;br /&gt;
&lt;br /&gt;
=== 11.1. Identifier les fichiers réellement exécutés ===&lt;br /&gt;
&lt;br /&gt;
La recette du 16 octobre utilise le dossier /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/. Elle ne démontre pas une mise à jour globale de /usr/local/sbin/. Toujours distinguer le lot validé et les programmes installés.&lt;br /&gt;
&lt;br /&gt;
Dans le dossier de recette :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy --help&lt;br /&gt;
./ajlsm-deploy-cycle --help&lt;br /&gt;
./ajlsm-deploy-yaml --help&lt;br /&gt;
python3 -m py_compile ajlsm-deploy ajlsm-deploy-check ajlsm-deploy-resources ajlsm-deploy-cycle ajlsm-deploy-yaml ajlsm_deploy_common.py ajlsm_deploy_rootgrow.py ajlsm_deploy_postconfig.py&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Une compilation vérifie la syntaxe, pas le bon déroulement d’une phase ni les prérequis serveur.&lt;br /&gt;
&lt;br /&gt;
=== 11.2. Sauvegarder et restaurer un lot cohérent ===&lt;br /&gt;
&lt;br /&gt;
Conserver ensemble programmes, modules et configuration de référence. Sauvegarder le lot complet avant une installation ou une correction. Exemple sur Saturne3 :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
tar -czf &amp;quot;/root/ajlsm-deploy/archives/lot-recette-$(date +%Y%m%d-%H%M%S).tar.gz&amp;quot; \&lt;br /&gt;
  -C /root/ajlsm-deploy/recettes/20261016 ajlsm-deploy-cycle&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Une restauration doit porter sur un ensemble compatible. Ne pas réinstaller uniquement ajlsm-deploy.bak-20261015 : ce fichier peut précéder les modules et phases nécessaires. L’ancienne sauvegarde et les répertoires de revue sont des références historiques à inventorier avant nettoyage.&lt;br /&gt;
&lt;br /&gt;
Ne pas supprimer INSTRUCTIONS-TEST.txt ou d’autres fichiers de /root/ajlsm-deploy-review/ sur la seule base de l’ancienne page. Leur archivage et le nettoyage ne font pas partie de cette mise à jour documentaire.&lt;br /&gt;
&lt;br /&gt;
=== 11.3. Page man ===&lt;br /&gt;
&lt;br /&gt;
La page du 15 octobre indique un manuel installé en /usr/local/man/man8/ajlsm-deploy.8 et une sauvegarde hors man8 dans /root/ajlsm-deploy-review/sauvegardes-man/. Ce sont des informations historiques, dont l’état actuel n’a pas été vérifié pendant la recette du 16 octobre.&lt;br /&gt;
&lt;br /&gt;
Pour identifier la page disponible sur Saturne3 :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man -w ajlsm-deploy&lt;br /&gt;
man 8 ajlsm-deploy&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Une page absente ne signifie pas que le script est absent : --help est l’aide intégrée de l’exécutable. Le manuel installé doit être réconcilié avec le cycle et l’assistant avant d’être considéré comme référence de cette version. En attendant, le présent guide et l’aide des fichiers du lot de recette décrivent le fonctionnement courant.&lt;br /&gt;
&lt;br /&gt;
== 12. État des validations et limites ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Date / source !! Vérification !! Portée&lt;br /&gt;
|-&lt;br /&gt;
| 15/10/2026, page historique || Déploiements initiaux jusqu’à l’activation réseau || Résultats historiques conservés ; ne décrivent pas à eux seuls le cycle actuel&lt;br /&gt;
|-&lt;br /&gt;
| 15/10/2026, page historique || Comparaison ED25519, clés divergentes ou malformées, préservation de known_hosts || Tests isolés rapportés dans la documentation reçue, non rejoués lors de cette consolidation&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, tests locaux du lot cycle || Ordre des 11 étapes, arrêt sur refus/erreur, reprise et suggestions || 8 tests réussis, incluant des sous-cas ; sous-processus des phases simulés&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, sorties Saturne3 transmises || Cycle technique complet sur un nouveau clone MERCURE3 || Terminé sans erreur signalée, extension racine incluse&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, sorties invitées transmises || SSH ajlsm, sudo, hostname et racine ext4 || Confirmés ; mercure3.ajlsm.com et 97 Gio pour /&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, tests locaux assistant || Création, correction, copie, validation et annulation || 14 tests réussis, saisies simulées&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, sortie Saturne3 transmise || Assistant --check sur mercure3.yaml || Valeurs YAML valides ; aucune écriture ni validation externe&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, vérification locale des modèles || Modèle vierge complété par l’assistant || Paramètres identiques à la référence MERCURE3 ; original intact&lt;br /&gt;
|-&lt;br /&gt;
| À réaliser || Essai réel du mécanisme de repli après échec d’activation réseau || Non confirmé ; le succès du parcours nominal ne valide pas ce scénario&lt;br /&gt;
|-&lt;br /&gt;
| À réaliser || Vérifications automatiques DNS, OPNsense, Ansible et recette applicative || Hors périmètre actuel&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le message de fin du cycle signifie que ses phases ont retourné un succès. Il ne vaut pas validation des applications ni détection de toutes les défaillances possibles. Conserver les vérifications finales et les limites propres aux phases.&lt;br /&gt;
&lt;br /&gt;
== 13. Réconciliation avec la page du 15 octobre ==&lt;br /&gt;
&lt;br /&gt;
L’original reçu est conservé intégralement dans historique/guide-20261015.mediawiki. Il sert de trace, pas de seconde procédure opérationnelle concurrente.&lt;br /&gt;
&lt;br /&gt;
Le présent document remplace les indications opérationnelles anciennes :&lt;br /&gt;
* confirmations CLONER/APPLIQUER/DEMARRER remplacées par OUI/NON ;&lt;br /&gt;
* parcours manuel seul remplacé par le choix entre mode manuel et cycle interactif ;&lt;br /&gt;
* liste des étapes incluant l’extension racine, SSH, mot de passe et TLS ;&lt;br /&gt;
* extension racine et cycle complet désormais validés sur la recette du 16 octobre ;&lt;br /&gt;
* suggestions manuelles affichant les deux commandes disponibles, sans oublier l’extension racine ;&lt;br /&gt;
* création et relecture du YAML par l’assistant, sans écraser l’original ;&lt;br /&gt;
* ajout du modèle vierge et de la référence MERCURE3 renseignée ;&lt;br /&gt;
* séparation explicite des scripts installés, du lot de recette, du manuel historique et de la future installation.&lt;br /&gt;
&lt;br /&gt;
Les détails encore utiles de l’ancienne page sur l’isolation, les transactions, ED25519, les sauvegardes, le README applicatif et les limites de validation sont repris ci-dessus. Une nouvelle mise à jour fonctionnelle doit modifier cette procédure directement plutôt que superposer une nouvelle section corrective à une ancienne procédure contradictoire.&lt;br /&gt;
&lt;br /&gt;
== 14. Suites prévues ==&lt;br /&gt;
&lt;br /&gt;
Prévoir les paramètres NFS, sites Apache2, Pleade, Drupal et Matomo dans le même YAML lorsque leurs exigences seront définies. Modifier ensemble le schéma, l’assistant, les modèles, les précontrôles, les phases et leur documentation. Documenter les références aux secrets plutôt que leurs valeurs.&lt;br /&gt;
&lt;br /&gt;
L’intégration des contrôles DNS, OPNsense et Ansible précédera une déclaration automatisée de disponibilité du projet. Le modèle actuel ne contient pas encore ces nouvelles sections.&lt;br /&gt;
&lt;br /&gt;
[[Catégorie:Infrastructure]]&lt;br /&gt;
[[Catégorie:Proxmox]]&lt;br /&gt;
[[Catégorie:Déploiement]]&lt;br /&gt;
[[Catégorie:AJLSM]]&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=AJLSM-DEPLOY_%E2%80%94_D%C3%A9ploiement_automatis%C3%A9_des_VM_Proxmox&amp;diff=6492</id>
		<title>AJLSM-DEPLOY — Déploiement automatisé des VM Proxmox</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=AJLSM-DEPLOY_%E2%80%94_D%C3%A9ploiement_automatis%C3%A9_des_VM_Proxmox&amp;diff=6492"/>
		<updated>2026-10-16T16:18:24Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : Contenu remplacé par « Obsolète :

Voir Déploiement_technique_d’une_VM_AJLSM »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Obsolète :&lt;br /&gt;
&lt;br /&gt;
Voir [[Déploiement_technique_d’une_VM_AJLSM]]&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=D%C3%A9ploiement_technique_d%E2%80%99une_VM_AJLSM&amp;diff=6491</id>
		<title>Déploiement technique d’une VM AJLSM</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=D%C3%A9ploiement_technique_d%E2%80%99une_VM_AJLSM&amp;diff=6491"/>
		<updated>2026-10-16T15:44:55Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= AJLSM-DEPLOY — Déploiement automatisé des VM Proxmox =&lt;br /&gt;
&lt;br /&gt;
Document consolidé au 16 octobre 2026. Cette procédure réunit la page du 15 octobre et la recette actuelle. Elle remplace leurs indications opérationnelles divergentes. L’original du 15 octobre reste archivé séparément.&lt;br /&gt;
&lt;br /&gt;
Référence technique : scripts reçus de Saturne3, puis lot de recette avec lanceur du cycle et assistant YAML.&lt;br /&gt;
&lt;br /&gt;
== 1. Périmètre et résultat de la recette ==&lt;br /&gt;
&lt;br /&gt;
Le cycle technique a été exécuté sur MERCURE3 sans erreur signalée. Les vérifications finales transmises confirment :&lt;br /&gt;
* connexion SSH avec le compte ajlsm ;&lt;br /&gt;
* élévation sudo avec le mot de passe défini pendant le cycle ;&lt;br /&gt;
* hostname mercure3.ajlsm.com ;&lt;br /&gt;
* volume racine ext4 de 97 Gio, dont 85 Gio disponibles lors du contrôle.&lt;br /&gt;
&lt;br /&gt;
Le cycle couvre le clonage, les ressources, l’initialisation du clone, l’extension de la racine, l’identité système, le réseau, SSH, le mot de passe et le certificat TLS interne.&lt;br /&gt;
&lt;br /&gt;
NFS, les configurations applicatives Apache2, Pleade, Drupal et Matomo ne font pas encore partie de ce cycle. Certains logiciels peuvent déjà être présents dans le modèle : leur présence ne constitue pas une configuration applicative du projet.&lt;br /&gt;
&lt;br /&gt;
== 2. Où exécuter les commandes ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Machine !! Rôle !! Exemple d’invite&lt;br /&gt;
|-&lt;br /&gt;
| Mac de l’administrateur || Transfert des archives par scp || Invite locale du Mac&lt;br /&gt;
|-&lt;br /&gt;
| Saturne3 || Préparation YAML, scripts Proxmox et cycle || root@Saturne3&lt;br /&gt;
|-&lt;br /&gt;
| MERCURE3 || Vérifications dans la VM || ajlsm@mercure3 ou root@mercure3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les scripts de déploiement sont exécutés sur Saturne3, pas dans MERCURE3.&lt;br /&gt;
Après « ssh ajlsm@10.0.0.43 », attendre l’invite de la VM avant de saisir les commandes suivantes.&lt;br /&gt;
Pour revenir de root@mercure3 à Saturne3 : un exit quitte sudo, puis un second exit ferme SSH.&lt;br /&gt;
&lt;br /&gt;
== 3. Organisation des fichiers ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/root/ajlsm-deploy/&lt;br /&gt;
  archives/                         Archives reçues, conservées comme références&lt;br /&gt;
  recettes/20261016/&lt;br /&gt;
    ajlsm-deploy-cycle/             Lot technique validé et assistant ajouté&lt;br /&gt;
    ajlsm-deploy-assistant/         Distribution de l’assistant et tests&lt;br /&gt;
    ajlsm-deploy-documentation/     Présent guide et modèles YAML&lt;br /&gt;
&lt;br /&gt;
/etc/ajlsm/deploy/projets/mercure3.yaml   Configuration actuellement utilisée&lt;br /&gt;
/usr/local/sbin/                        Scripts installés antérieurement&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le lot de recette contient ajlsm-deploy, ajlsm-deploy-check, ajlsm-deploy-resources, ajlsm-deploy-cycle et les modules ajlsm_deploy_common.py, ajlsm_deploy_rootgrow.py et ajlsm_deploy_postconfig.py. L’assistant ajlsm-deploy-yaml a été ajouté à ce même dossier.&lt;br /&gt;
&lt;br /&gt;
Conserver exécutables et modules ensemble. Utiliser les chemins ./ depuis le dossier de recette pour ne pas appeler une ancienne version de /usr/local/sbin.&lt;br /&gt;
Les anciennes archives « ajlsm-deploy-revise » et « correction-suggestions » ne sont pas la référence courante : elles précèdent les phases supplémentaires reçues dans l’archive serveur.&lt;br /&gt;
&lt;br /&gt;
Prérequis : Python 3.9 ou supérieur, PyYAML 6, outils Proxmox sur le nœud cible et prérequis du modèle AJLSM. Les phases invitées utilisent notamment l’agent QEMU, ajlsm-clone-init, Python, systemd et Netplan. L’extension actuelle cible ext4/LVM sur /dev/sda3, avec un seul PV et un seul LV.&lt;br /&gt;
&lt;br /&gt;
== 4. Les deux fichiers de préconfiguration ==&lt;br /&gt;
&lt;br /&gt;
=== 4.1. projet-vierge.yaml ===&lt;br /&gt;
&lt;br /&gt;
Ce modèle reprend toute la structure actuelle sans valeur opérationnelle préremplie. Chaque champ doit être renseigné. Seul proxmox.vmid peut rester null : il signifie alors attribution automatique.&lt;br /&gt;
&lt;br /&gt;
Le modèle comporte deux interfaces dont les valeurs sont null. Adapter le nombre d’interfaces avant la saisie si nécessaire. Pour déterminer ce nombre par les questions de l’assistant, utiliser plutôt le mode --new.&lt;br /&gt;
&lt;br /&gt;
Un modèle vierge est volontairement refusé par --check. Il ne doit jamais être passé directement au lanceur du cycle.&lt;br /&gt;
&lt;br /&gt;
=== 4.2. mercure3-reference.yaml ===&lt;br /&gt;
&lt;br /&gt;
Ce fichier conserve les valeurs du projet validé : modèle 506 sur Saturne3, nom MERCURE3, 8 vCPU, 24576 Mio de RAM maximale, 16384 Mio minimale, disque 100 Gio, extension racine activée et paramètres réseau du projet.&lt;br /&gt;
&lt;br /&gt;
Il permet de reconstruire une nouvelle VM avec la même configuration technique si le modèle, le stockage, les bridges et les préparatifs externes sont toujours disponibles. Il ne sauvegarde ni les données de l’ancienne VM, ni ses UUID, machine-id, clés hôte SSH ou mots de passe. Ces identités sont traitées par le cycle et ne sont pas à recopier.&lt;br /&gt;
&lt;br /&gt;
Avec vmid: null, le VMID de remplacement peut différer de celui de l’ancienne VM. Le VMID 505 observé pendant la recette n’est pas une réservation permanente.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ne pas lancer cette référence tant que MERCURE3 existe encore.&#039;&#039;&#039; Le clonage refuse un nom déjà présent. Pour tester une deuxième VM en parallèle, définir un autre nom, hostname, des IP distinctes et préparer DNS/OPNsense/Ansible en conséquence.&lt;br /&gt;
&lt;br /&gt;
=== 4.3. Valeurs acceptées ===&lt;br /&gt;
&lt;br /&gt;
* projet.environnement et tags : interne, client, prod. Les tags sont une liste sans doublons ; [] est admis.&lt;br /&gt;
* CPU, mémoire et taille du disque : entiers strictement positifs ; mémoire minimale inférieure ou égale à la maximale.&lt;br /&gt;
* Booléens : utiliser true ou false sans guillemets.&lt;br /&gt;
* Interfaces Proxmox : net suivi de chiffres ; interfaces invitées : ens suivi de chiffres.&lt;br /&gt;
* Adresses d’interfaces : IPv4/CIDR. Loopback : IPv4/32. Passerelle et DNS : IPv4 sans préfixe.&lt;br /&gt;
* Passerelle : interface déclarée et adresse appartenant à son sous-réseau, distincte des adresses de la VM.&lt;br /&gt;
* Hostname : nom DNS en minuscules.&lt;br /&gt;
* Serveur, bridge et stockage : valeurs adaptées à l’infrastructure ; aucune liste fermée inventée.&lt;br /&gt;
&lt;br /&gt;
Les clés inconnues ou répétées sont refusées. Ne pas ajouter de sections applicatives avant l’évolution coordonnée du schéma et des scripts. Ne pas utiliser [à renseigner] : les crochets créent une liste YAML.&lt;br /&gt;
&lt;br /&gt;
== 5. Préparer et valider le YAML ==&lt;br /&gt;
&lt;br /&gt;
Sur Saturne3, se placer dans le lot de recette :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5.1. Vérifier un fichier existant sans le modifier ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml /etc/ajlsm/deploy/projets/mercure3.yaml --check&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le message de succès signifie que les valeurs et leur cohérence locale sont conformes. Il ne certifie pas la préparation des services externes.&lt;br /&gt;
&lt;br /&gt;
=== 5.2. Compléter le modèle vierge ===&lt;br /&gt;
&lt;br /&gt;
Après extraction du présent lot documentaire :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml \&lt;br /&gt;
  /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-documentation/projet-vierge.yaml \&lt;br /&gt;
  --output /root/ajlsm-deploy/recettes/20261016/nouveau-projet.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Toutes les valeurs obligatoires seront demandées. Pour saisir de nouveau le projet MERCURE3, consulter mercure3-reference.yaml comme fiche de paramètres, sans lancer de déploiement.&lt;br /&gt;
&lt;br /&gt;
=== 5.3. Créer sans modèle ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml /root/ajlsm-deploy/recettes/20261016/nouveau-projet.yaml --new&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette commande est une alternative à la précédente : le chemin doit être inexistant. L’assistant pose les questions, y compris le nombre d’interfaces, sans reprendre implicitement les valeurs de MERCURE3.&lt;br /&gt;
&lt;br /&gt;
=== 5.4. Revoir un projet renseigné ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml /etc/ajlsm/deploy/projets/mercure3.yaml --review \&lt;br /&gt;
  --output /root/ajlsm-deploy/recettes/20261016/mercure3-relecture.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Entrée conserve une valeur existante valide.&lt;br /&gt;
* ANNULER, Ctrl-C ou fin d’entrée abandonnent sans enregistrer.&lt;br /&gt;
* Tags et DNS sont saisis séparés par des virgules ; [] ou aucun signifie tags vides.&lt;br /&gt;
* Saisir auto ou null pour un VMID automatique.&lt;br /&gt;
* Après une incohérence, donner le chemin du champ à corriger ; ? affiche les chemins.&lt;br /&gt;
* Le résumé complet est présenté avant confirmation OUI/NON d’enregistrement.&lt;br /&gt;
&lt;br /&gt;
L’original reste intact, avec ses commentaires. La copie est réécrite en YAML, sans reprise des commentaires. Aucun fichier existant n’est écrasé. Si une destination existe, choisir un nouveau nom avec --output.&lt;br /&gt;
&lt;br /&gt;
=== 5.5. Préparatifs externes ===&lt;br /&gt;
&lt;br /&gt;
Avant une création, vérifier séparément la réservation des IP, les déclarations DNS, les règles/routes/NAT nécessaires dans OPNsense et l’inventaire ou les préparatifs Ansible. Ne pas inscrire de mots de passe dans le YAML ; conserver les secrets dans le dispositif prévu pour leur gestion.&lt;br /&gt;
&lt;br /&gt;
L’assistant actuel ne vérifie pas automatiquement ces services et ne marque pas un projet « prêt à déployer » sur cette seule base. Leur intégration reste à réaliser.&lt;br /&gt;
&lt;br /&gt;
Le contrôle Proxmox autonome examine notamment le modèle, ses ressources, le stockage et les bridges. Il concerne une nouvelle création et peut refuser un projet déjà déployé :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-check /chemin/vers/projet.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 6. Afficher le plan puis lancer le cycle ==&lt;br /&gt;
&lt;br /&gt;
=== 6.1. Plan sans exécution ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /chemin/vers/projet.yaml --plan&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le plan valide le YAML et affiche les commandes, sans exécuter les phases ni vérifier l’infrastructure. Il doit contenir les 11 étapes, toutes dans le dossier de recette.&lt;br /&gt;
&lt;br /&gt;
=== 6.2. Cycle réel pour une nouvelle VM ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /chemin/vers/projet.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le lanceur exécute les phases réelles, sans simulation automatique. Il attend seulement les confirmations, les saisies nécessaires et la fin de chaque commande. Il s’arrête sur refus ou erreur. Il ne répond pas à la place de l’administrateur et ne capture pas les mots de passe.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! N° !! Étape !! Commande réelle !! Simulation facultative&lt;br /&gt;
|-&lt;br /&gt;
| 1 || Clonage || --clone || --dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Ressources || --configure-resources || --resources-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Premier démarrage isolé || --first-boot-apply || --first-boot-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Extension partition/LVM/ext4 || --root-grow-apply || --root-grow-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Identité système || --system-apply || --system-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Préparation Netplan || --network-apply || --network-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Activation réseau || --network-enable || --network-enable-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Audit SSH || --ssh-audit || Aucune option dédiée&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Sécurisation SSH || --ssh-secure || Aucune option dédiée&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Mot de passe ajlsm || --password-ajlsm || Aucune option dédiée&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Certificat TLS interne || --tls-apply || Aucune option dédiée&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
L’extension racine est indispensable quand etendre_volume_racine vaut true. Agrandir le disque Proxmox ne suffit pas : la partition, le PV LVM, le LV et ext4 doivent aussi être étendus. Cette phase doit figurer après le premier démarrage, avant la personnalisation système. Avec false, la phase annonce sa désactivation.&lt;br /&gt;
&lt;br /&gt;
Le démarrage et la personnalisation se font réseau isolé. Netplan est préparé avant activation des liens. La phase d’activation contrôle le réseau et applique demarrage_auto.&lt;br /&gt;
&lt;br /&gt;
Le certificat TLS interne ne constitue pas, à lui seul, une configuration des applications du projet ou un certificat publiquement reconnu.&lt;br /&gt;
&lt;br /&gt;
=== 6.3. Mode manuel ===&lt;br /&gt;
&lt;br /&gt;
Chaque phase peut être lancée séparément avec ./ajlsm-deploy suivi du YAML et de son option. Après succès, le lot courant affiche deux lignes pour l’étape suivante : Simulation et Exécution. Si la simulation n’existe pas, il le signale. Aucune suggestion n’est exécutée automatiquement.&lt;br /&gt;
&lt;br /&gt;
Les simulations peuvent consulter l’invité et émettre des sondes ARP selon la phase : elles ne sont pas toutes des contrôles hors ligne. L’absence de réponse ARP ne remplace pas la réservation des adresses dans l’inventaire réseau.&lt;br /&gt;
&lt;br /&gt;
== 7. Erreur, annulation et reprise ==&lt;br /&gt;
&lt;br /&gt;
Conserver la sortie complète et diagnostiquer la phase fautive avant de reprendre. Une phase peut être partiellement effectuée ; le lanceur n’effectue ni suppression de VM ni restauration globale automatique.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /chemin/vers/projet.yaml --from extension-racine&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--from inclut l’étape indiquée et saute les précédentes à la demande de l’administrateur. Il ne certifie pas leur état. Les contrôles propres aux phases restent actifs. Le lanceur ne possède pas de journal persistant global de progression.&lt;br /&gt;
&lt;br /&gt;
Ne pas relancer le cycle depuis le clonage sur une VM existante pour terminer une étape. Ne pas relancer des étapes déjà terminées uniquement parce qu’une commande manuelle les suggère. Les suggestions suivent l’ordre théorique et ne constituent pas un inventaire de l’état de la VM.&lt;br /&gt;
&lt;br /&gt;
Codes de sortie : 0 succès, 1 annulation, 2 erreur. Le lanceur normalise les autres codes d’échec de ses sous-processus en erreur et ne poursuit pas.&lt;br /&gt;
&lt;br /&gt;
== 8. Vérifications finales ==&lt;br /&gt;
&lt;br /&gt;
Sur Saturne3, avec le VMID réellement annoncé au clonage :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
qm list&lt;br /&gt;
qm status VMID&lt;br /&gt;
qm config VMID&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remplacer VMID par l’identifiant vérifié. Contrôler le nom, les CPU, la RAM, le disque, les liens réseau et onboot selon le YAML.&lt;br /&gt;
&lt;br /&gt;
Depuis Saturne3, ouvrir la connexion et attendre l’invite de la VM :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh ajlsm@10.0.0.43&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dans MERCURE3, saisir sudo -i, attendre l’authentification et l’invite root, puis :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
hostname&lt;br /&gt;
lsblk&lt;br /&gt;
df -hT /&lt;br /&gt;
ip -br addr&lt;br /&gt;
ip route&lt;br /&gt;
resolvectl status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat vérifié pendant la recette : hostname mercure3.ajlsm.com, racine ext4 97 Gio. Les tailles disponibles évoluent avec l’utilisation. Les commandes SSH et TLS du cycle vérifient leurs propres résultats ; compléter par les tests d’accès attendus dans le réseau cible.&lt;br /&gt;
&lt;br /&gt;
== 9. Reconstruire MERCURE3 ultérieurement ==&lt;br /&gt;
&lt;br /&gt;
# Conserver le fichier mercure3-reference.yaml, le lot de scripts validé et l’identification du modèle utilisé.&lt;br /&gt;
# Comparer la référence au YAML effectivement utilisé avant reconstruction ; actualiser les changements d’infrastructure.&lt;br /&gt;
# Identifier et sauvegarder les données à conserver : le YAML n’est pas une sauvegarde de VM.&lt;br /&gt;
# Vérifier explicitement l’identité de l’ancienne VM et traiter séparément son arrêt et sa suppression volontaire. Le cycle ne détruit jamais automatiquement une VM existante.&lt;br /&gt;
# Contrôler DNS, OPNsense, Ansible et les réservations d’IP. Ne pas laisser deux VM actives avec les mêmes adresses.&lt;br /&gt;
# Valider la référence avec --check, afficher le --plan, puis lancer le cycle sur la référence après libération de la cible.&lt;br /&gt;
# Relever le nouveau VMID et effectuer les vérifications finales.&lt;br /&gt;
&lt;br /&gt;
On retrouve ainsi les paramètres de la VM, sans chercher à reproduire ses anciennes identités techniques.&lt;br /&gt;
&lt;br /&gt;
== 10. Protections et détails techniques ==&lt;br /&gt;
&lt;br /&gt;
=== 10.1. Isolation, identité et journal de personnalisation ===&lt;br /&gt;
&lt;br /&gt;
Le clone est arrêté après création, avec onboot désactivé et les interfaces isolées. Le premier démarrage s’effectue dans cet état d’isolation. Les phases système et réseau vérifient l’identité de la cible et l’UUID attendu selon leurs contrôles propres.&lt;br /&gt;
&lt;br /&gt;
La personnalisation système conserve dans l’invité :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/var/lib/ajlsm/system-personalisation/state.json&lt;br /&gt;
/var/lib/ajlsm/system-personalisation/backup/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce journal décrit la transaction d’identité, pas l’ensemble du cycle. Ne pas le supprimer pour forcer une nouvelle exécution. Après interruption, conserver les sauvegardes et examiner l’état réel avant reprise.&lt;br /&gt;
&lt;br /&gt;
La VM 515 est signalée comme hors périmètre par la documentation historique. Elle ne fait pas partie de la recette MERCURE3 et ne doit pas être ciblée par cette procédure.&lt;br /&gt;
&lt;br /&gt;
=== 10.2. Audit SSH : lecture dans la VM, écriture possible sur Saturne3 ===&lt;br /&gt;
&lt;br /&gt;
La phase --ssh-audit commence par synchroniser l’identité SSH :&lt;br /&gt;
# Lire la clé publique /etc/ssh/ssh_host_ed25519_key.pub dans la VM via l’agent QEMU.&lt;br /&gt;
# Valider le format ED25519 et sa structure binaire attendue.&lt;br /&gt;
# Lire indépendamment la clé exposée sur le réseau avec ssh-keyscan -T 8 -t ed25519.&lt;br /&gt;
# Comparer les clés : une divergence, une absence ou un format invalide provoque un refus.&lt;br /&gt;
# Après concordance seulement, sauvegarder /root/.ssh/known_hosts sur Saturne3, travailler sur une copie et remplacer le fichier avec la nouvelle entrée vérifiée pour l’IP cible.&lt;br /&gt;
# Contrôler les connexions par clé, les clés autorisées, sudo et l’état du compte ajlsm.&lt;br /&gt;
&lt;br /&gt;
Les autres entrées d’hôtes sont conservées ; le traitement retire aussi les anciennes entrées hachées correspondant à l’IP cible. Les sauvegardes utilisent le préfixe known_hosts.ajlsm-backup. dans /root/.ssh/.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;L’audit n’est donc pas entièrement sans écriture :&#039;&#039;&#039; ses lectures dans la VM sont accompagnées d’une mise à jour possible de known_hosts sur Saturne3. Ne jamais contourner une divergence en effaçant aveuglément known_hosts.&lt;br /&gt;
&lt;br /&gt;
=== 10.3. Sécurisation SSH et mot de passe ===&lt;br /&gt;
&lt;br /&gt;
--ssh-secure effectue un audit préalable, prépare un fichier SSH dédié, vérifie la syntaxe et les valeurs effectives, puis recharge SSH. Il désactive l’authentification SSH par mot de passe et conserve root par clé. Les connexions root et ajlsm par clé sont revérifiées par le code reçu.&lt;br /&gt;
&lt;br /&gt;
Le mot de passe local ajlsm reste utile pour sudo. --password-ajlsm utilise un terminal interactif et lance passwd dans la VM, avec sa double saisie masquée. Le secret n’est pas inscrit dans le YAML ni dans la ligne de commande. La procédure historique prévoit un report manuel dans le registre ODS d’administration ; appliquer les règles internes de gestion des secrets. Ne pas joindre ce registre à une documentation publique.&lt;br /&gt;
&lt;br /&gt;
=== 10.4. Certificat TLS interne et Apache ===&lt;br /&gt;
&lt;br /&gt;
--tls-apply lit le certificat /etc/ssl/ajlsm/server.crt. Si le CN et le SAN correspondent déjà au hostname attendu, la phase termine sans réinitialisation. Sinon, après confirmation, elle appelle /usr/local/sbin/ajlsm-init-tls.sh &#039;&#039;&#039;dans la VM&#039;&#039;&#039;. Ce dernier script doit être présent dans le modèle ; son contenu n’était pas inclus dans l’archive des scripts de déploiement reçue.&lt;br /&gt;
&lt;br /&gt;
Après une initialisation réussie, le module contrôle le certificat, apache2ctl configtest et systemctl is-active apache2. Ce contrôle technique d’Apache ne constitue pas une recette des VirtualHosts et des applications du projet.&lt;br /&gt;
&lt;br /&gt;
La documentation historique désigne /home/ajlsm/README, hérité de TEMPLATE3, comme README applicatif Pleade/Drupal. Le conserver séparément du README-ajlsm-deploy de l’outil de déploiement ; ne pas remplacer l’un par l’autre.&lt;br /&gt;
&lt;br /&gt;
=== 10.5. Attente réseau au premier démarrage ===&lt;br /&gt;
&lt;br /&gt;
La recette du 15 octobre signalait environ 60 secondes d’attente dans systemd-networkd-wait-online lorsque les interfaces étaient isolées. Ce constat historique n’a pas empêché l’agent QEMU ni ajlsm-clone-init de répondre. Une optimisation éventuelle du modèle reste distincte du déploiement ; ne pas désactiver le service sans vérifier ses dépendances.&lt;br /&gt;
&lt;br /&gt;
== 11. Maintenance, sauvegardes et manuel ==&lt;br /&gt;
&lt;br /&gt;
=== 11.1. Identifier les fichiers réellement exécutés ===&lt;br /&gt;
&lt;br /&gt;
La recette du 16 octobre utilise le dossier /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle/. Elle ne démontre pas une mise à jour globale de /usr/local/sbin/. Toujours distinguer le lot validé et les programmes installés.&lt;br /&gt;
&lt;br /&gt;
Dans le dossier de recette :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy --help&lt;br /&gt;
./ajlsm-deploy-cycle --help&lt;br /&gt;
./ajlsm-deploy-yaml --help&lt;br /&gt;
python3 -m py_compile ajlsm-deploy ajlsm-deploy-check ajlsm-deploy-resources ajlsm-deploy-cycle ajlsm-deploy-yaml ajlsm_deploy_common.py ajlsm_deploy_rootgrow.py ajlsm_deploy_postconfig.py&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Une compilation vérifie la syntaxe, pas le bon déroulement d’une phase ni les prérequis serveur.&lt;br /&gt;
&lt;br /&gt;
=== 11.2. Sauvegarder et restaurer un lot cohérent ===&lt;br /&gt;
&lt;br /&gt;
Conserver ensemble programmes, modules et configuration de référence. Sauvegarder le lot complet avant une installation ou une correction. Exemple sur Saturne3 :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
tar -czf &amp;quot;/root/ajlsm-deploy/archives/lot-recette-$(date +%Y%m%d-%H%M%S).tar.gz&amp;quot; \&lt;br /&gt;
  -C /root/ajlsm-deploy/recettes/20261016 ajlsm-deploy-cycle&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Une restauration doit porter sur un ensemble compatible. Ne pas réinstaller uniquement ajlsm-deploy.bak-20261015 : ce fichier peut précéder les modules et phases nécessaires. L’ancienne sauvegarde et les répertoires de revue sont des références historiques à inventorier avant nettoyage.&lt;br /&gt;
&lt;br /&gt;
Ne pas supprimer INSTRUCTIONS-TEST.txt ou d’autres fichiers de /root/ajlsm-deploy-review/ sur la seule base de l’ancienne page. Leur archivage et le nettoyage ne font pas partie de cette mise à jour documentaire.&lt;br /&gt;
&lt;br /&gt;
=== 11.3. Page man ===&lt;br /&gt;
&lt;br /&gt;
La page du 15 octobre indique un manuel installé en /usr/local/man/man8/ajlsm-deploy.8 et une sauvegarde hors man8 dans /root/ajlsm-deploy-review/sauvegardes-man/. Ce sont des informations historiques, dont l’état actuel n’a pas été vérifié pendant la recette du 16 octobre.&lt;br /&gt;
&lt;br /&gt;
Pour identifier la page disponible sur Saturne3 :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
man -w ajlsm-deploy&lt;br /&gt;
man 8 ajlsm-deploy&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Une page absente ne signifie pas que le script est absent : --help est l’aide intégrée de l’exécutable. Le manuel installé doit être réconcilié avec le cycle et l’assistant avant d’être considéré comme référence de cette version. En attendant, le présent guide et l’aide des fichiers du lot de recette décrivent le fonctionnement courant.&lt;br /&gt;
&lt;br /&gt;
== 12. État des validations et limites ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Date / source !! Vérification !! Portée&lt;br /&gt;
|-&lt;br /&gt;
| 15/10/2026, page historique || Déploiements initiaux jusqu’à l’activation réseau || Résultats historiques conservés ; ne décrivent pas à eux seuls le cycle actuel&lt;br /&gt;
|-&lt;br /&gt;
| 15/10/2026, page historique || Comparaison ED25519, clés divergentes ou malformées, préservation de known_hosts || Tests isolés rapportés dans la documentation reçue, non rejoués lors de cette consolidation&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, tests locaux du lot cycle || Ordre des 11 étapes, arrêt sur refus/erreur, reprise et suggestions || 8 tests réussis, incluant des sous-cas ; sous-processus des phases simulés&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, sorties Saturne3 transmises || Cycle technique complet sur un nouveau clone MERCURE3 || Terminé sans erreur signalée, extension racine incluse&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, sorties invitées transmises || SSH ajlsm, sudo, hostname et racine ext4 || Confirmés ; mercure3.ajlsm.com et 97 Gio pour /&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, tests locaux assistant || Création, correction, copie, validation et annulation || 14 tests réussis, saisies simulées&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, sortie Saturne3 transmise || Assistant --check sur mercure3.yaml || Valeurs YAML valides ; aucune écriture ni validation externe&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026, vérification locale des modèles || Modèle vierge complété par l’assistant || Paramètres identiques à la référence MERCURE3 ; original intact&lt;br /&gt;
|-&lt;br /&gt;
| À réaliser || Essai réel du mécanisme de repli après échec d’activation réseau || Non confirmé ; le succès du parcours nominal ne valide pas ce scénario&lt;br /&gt;
|-&lt;br /&gt;
| À réaliser || Vérifications automatiques DNS, OPNsense, Ansible et recette applicative || Hors périmètre actuel&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le message de fin du cycle signifie que ses phases ont retourné un succès. Il ne vaut pas validation des applications ni détection de toutes les défaillances possibles. Conserver les vérifications finales et les limites propres aux phases.&lt;br /&gt;
&lt;br /&gt;
== 13. Réconciliation avec la page du 15 octobre ==&lt;br /&gt;
&lt;br /&gt;
L’original reçu est conservé intégralement dans historique/guide-20261015.mediawiki. Il sert de trace, pas de seconde procédure opérationnelle concurrente.&lt;br /&gt;
&lt;br /&gt;
Le présent document remplace les indications opérationnelles anciennes :&lt;br /&gt;
* confirmations CLONER/APPLIQUER/DEMARRER remplacées par OUI/NON ;&lt;br /&gt;
* parcours manuel seul remplacé par le choix entre mode manuel et cycle interactif ;&lt;br /&gt;
* liste des étapes incluant l’extension racine, SSH, mot de passe et TLS ;&lt;br /&gt;
* extension racine et cycle complet désormais validés sur la recette du 16 octobre ;&lt;br /&gt;
* suggestions manuelles affichant les deux commandes disponibles, sans oublier l’extension racine ;&lt;br /&gt;
* création et relecture du YAML par l’assistant, sans écraser l’original ;&lt;br /&gt;
* ajout du modèle vierge et de la référence MERCURE3 renseignée ;&lt;br /&gt;
* séparation explicite des scripts installés, du lot de recette, du manuel historique et de la future installation.&lt;br /&gt;
&lt;br /&gt;
Les détails encore utiles de l’ancienne page sur l’isolation, les transactions, ED25519, les sauvegardes, le README applicatif et les limites de validation sont repris ci-dessus. Une nouvelle mise à jour fonctionnelle doit modifier cette procédure directement plutôt que superposer une nouvelle section corrective à une ancienne procédure contradictoire.&lt;br /&gt;
&lt;br /&gt;
== 14. Suites prévues ==&lt;br /&gt;
&lt;br /&gt;
Prévoir les paramètres NFS, sites Apache2, Pleade, Drupal et Matomo dans le même YAML lorsque leurs exigences seront définies. Modifier ensemble le schéma, l’assistant, les modèles, les précontrôles, les phases et leur documentation. Documenter les références aux secrets plutôt que leurs valeurs.&lt;br /&gt;
&lt;br /&gt;
L’intégration des contrôles DNS, OPNsense et Ansible précédera une déclaration automatisée de disponibilité du projet. Le modèle actuel ne contient pas encore ces nouvelles sections.&lt;br /&gt;
&lt;br /&gt;
[[Catégorie:Infrastructure]]&lt;br /&gt;
[[Catégorie:Proxmox]]&lt;br /&gt;
[[Catégorie:Déploiement]]&lt;br /&gt;
[[Catégorie:AJLSM]]&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=D%C3%A9ploiement_technique_d%E2%80%99une_VM_AJLSM&amp;diff=6490</id>
		<title>Déploiement technique d’une VM AJLSM</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=D%C3%A9ploiement_technique_d%E2%80%99une_VM_AJLSM&amp;diff=6490"/>
		<updated>2026-10-16T15:37:53Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : Page créée avec « = Déploiement technique d’une VM AJLSM =  Document du 16 octobre 2026. Référence : scripts reçus de Saturne3, puis lot de recette avec lanceur du cycle et assistant ... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Déploiement technique d’une VM AJLSM =&lt;br /&gt;
&lt;br /&gt;
Document du 16 octobre 2026. Référence : scripts reçus de Saturne3, puis lot de recette avec lanceur du cycle et assistant YAML.&lt;br /&gt;
&lt;br /&gt;
== 1. Périmètre et résultat de la recette ==&lt;br /&gt;
&lt;br /&gt;
Le cycle technique a été exécuté sur MERCURE3 sans erreur signalée. Les vérifications finales transmises confirment :&lt;br /&gt;
* connexion SSH avec le compte ajlsm ;&lt;br /&gt;
* élévation sudo avec le mot de passe défini pendant le cycle ;&lt;br /&gt;
* hostname mercure3.ajlsm.com ;&lt;br /&gt;
* volume racine ext4 de 97 Gio, dont 85 Gio disponibles lors du contrôle.&lt;br /&gt;
&lt;br /&gt;
Le cycle couvre le clonage, les ressources, l’initialisation du clone, l’extension de la racine, l’identité système, le réseau, SSH, le mot de passe et le certificat TLS interne.&lt;br /&gt;
&lt;br /&gt;
NFS, les configurations applicatives Apache2, Pleade, Drupal et Matomo ne font pas encore partie de ce cycle. Certains logiciels peuvent déjà être présents dans le modèle : leur présence ne constitue pas une configuration applicative du projet.&lt;br /&gt;
&lt;br /&gt;
== 2. Où exécuter les commandes ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Machine !! Rôle !! Exemple d’invite&lt;br /&gt;
|-&lt;br /&gt;
| Mac de l’administrateur || Transfert des archives par scp || Invite locale du Mac&lt;br /&gt;
|-&lt;br /&gt;
| Saturne3 || Préparation YAML, scripts Proxmox et cycle || root@Saturne3&lt;br /&gt;
|-&lt;br /&gt;
| MERCURE3 || Vérifications dans la VM || ajlsm@mercure3 ou root@mercure3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les scripts de déploiement sont exécutés sur Saturne3, pas dans MERCURE3.&lt;br /&gt;
Après « ssh ajlsm@10.0.0.43 », attendre l’invite de la VM avant de saisir les commandes suivantes.&lt;br /&gt;
Pour revenir de root@mercure3 à Saturne3 : un exit quitte sudo, puis un second exit ferme SSH.&lt;br /&gt;
&lt;br /&gt;
== 3. Organisation des fichiers ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/root/ajlsm-deploy/&lt;br /&gt;
  archives/                         Archives reçues, conservées comme références&lt;br /&gt;
  recettes/20261016/&lt;br /&gt;
    ajlsm-deploy-cycle/             Lot technique validé et assistant ajouté&lt;br /&gt;
    ajlsm-deploy-assistant/         Distribution de l’assistant et tests&lt;br /&gt;
    ajlsm-deploy-documentation/     Présent guide et modèles YAML&lt;br /&gt;
&lt;br /&gt;
/etc/ajlsm/deploy/projets/mercure3.yaml   Configuration actuellement utilisée&lt;br /&gt;
/usr/local/sbin/                        Scripts installés antérieurement&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le lot de recette contient ajlsm-deploy, ajlsm-deploy-check, ajlsm-deploy-resources, ajlsm-deploy-cycle et les modules ajlsm_deploy_common.py, ajlsm_deploy_rootgrow.py et ajlsm_deploy_postconfig.py. L’assistant ajlsm-deploy-yaml a été ajouté à ce même dossier.&lt;br /&gt;
&lt;br /&gt;
Conserver exécutables et modules ensemble. Utiliser les chemins ./ depuis le dossier de recette pour ne pas appeler une ancienne version de /usr/local/sbin.&lt;br /&gt;
Les anciennes archives « ajlsm-deploy-revise » et « correction-suggestions » ne sont pas la référence courante : elles précèdent les phases supplémentaires reçues dans l’archive serveur.&lt;br /&gt;
&lt;br /&gt;
Prérequis : Python 3.9 ou supérieur, PyYAML 6, outils Proxmox sur le nœud cible et prérequis du modèle AJLSM. Les phases invitées utilisent notamment l’agent QEMU, ajlsm-clone-init, Python, systemd et Netplan. L’extension actuelle cible ext4/LVM sur /dev/sda3, avec un seul PV et un seul LV.&lt;br /&gt;
&lt;br /&gt;
== 4. Les deux fichiers de préconfiguration ==&lt;br /&gt;
&lt;br /&gt;
=== 4.1. projet-vierge.yaml ===&lt;br /&gt;
&lt;br /&gt;
Ce modèle reprend toute la structure actuelle sans valeur opérationnelle préremplie. Chaque champ doit être renseigné. Seul proxmox.vmid peut rester null : il signifie alors attribution automatique.&lt;br /&gt;
&lt;br /&gt;
Le modèle comporte deux interfaces dont les valeurs sont null. Adapter le nombre d’interfaces avant la saisie si nécessaire. Pour déterminer ce nombre par les questions de l’assistant, utiliser plutôt le mode --new.&lt;br /&gt;
&lt;br /&gt;
Un modèle vierge est volontairement refusé par --check. Il ne doit jamais être passé directement au lanceur du cycle.&lt;br /&gt;
&lt;br /&gt;
=== 4.2. mercure3-reference.yaml ===&lt;br /&gt;
&lt;br /&gt;
Ce fichier conserve les valeurs du projet validé : modèle 506 sur Saturne3, nom MERCURE3, 8 vCPU, 24576 Mio de RAM maximale, 16384 Mio minimale, disque 100 Gio, extension racine activée et paramètres réseau du projet.&lt;br /&gt;
&lt;br /&gt;
Il permet de reconstruire une nouvelle VM avec la même configuration technique si le modèle, le stockage, les bridges et les préparatifs externes sont toujours disponibles. Il ne sauvegarde ni les données de l’ancienne VM, ni ses UUID, machine-id, clés hôte SSH ou mots de passe. Ces identités sont traitées par le cycle et ne sont pas à recopier.&lt;br /&gt;
&lt;br /&gt;
Avec vmid: null, le VMID de remplacement peut différer de celui de l’ancienne VM. Le VMID 505 observé pendant la recette n’est pas une réservation permanente.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ne pas lancer cette référence tant que MERCURE3 existe encore.&#039;&#039;&#039; Le clonage refuse un nom déjà présent. Pour tester une deuxième VM en parallèle, définir un autre nom, hostname, des IP distinctes et préparer DNS/OPNsense/Ansible en conséquence.&lt;br /&gt;
&lt;br /&gt;
=== 4.3. Valeurs acceptées ===&lt;br /&gt;
&lt;br /&gt;
* projet.environnement et tags : interne, client, prod. Les tags sont une liste sans doublons ; [] est admis.&lt;br /&gt;
* CPU, mémoire et taille du disque : entiers strictement positifs ; mémoire minimale inférieure ou égale à la maximale.&lt;br /&gt;
* Booléens : utiliser true ou false sans guillemets.&lt;br /&gt;
* Interfaces Proxmox : net suivi de chiffres ; interfaces invitées : ens suivi de chiffres.&lt;br /&gt;
* Adresses d’interfaces : IPv4/CIDR. Loopback : IPv4/32. Passerelle et DNS : IPv4 sans préfixe.&lt;br /&gt;
* Passerelle : interface déclarée et adresse appartenant à son sous-réseau, distincte des adresses de la VM.&lt;br /&gt;
* Hostname : nom DNS en minuscules.&lt;br /&gt;
* Serveur, bridge et stockage : valeurs adaptées à l’infrastructure ; aucune liste fermée inventée.&lt;br /&gt;
&lt;br /&gt;
Les clés inconnues ou répétées sont refusées. Ne pas ajouter de sections applicatives avant l’évolution coordonnée du schéma et des scripts. Ne pas utiliser [à renseigner] : les crochets créent une liste YAML.&lt;br /&gt;
&lt;br /&gt;
== 5. Préparer et valider le YAML ==&lt;br /&gt;
&lt;br /&gt;
Sur Saturne3, se placer dans le lot de recette :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-cycle&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5.1. Vérifier un fichier existant sans le modifier ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml /etc/ajlsm/deploy/projets/mercure3.yaml --check&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le message de succès signifie que les valeurs et leur cohérence locale sont conformes. Il ne certifie pas la préparation des services externes.&lt;br /&gt;
&lt;br /&gt;
=== 5.2. Compléter le modèle vierge ===&lt;br /&gt;
&lt;br /&gt;
Après extraction du présent lot documentaire :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml \&lt;br /&gt;
  /root/ajlsm-deploy/recettes/20261016/ajlsm-deploy-documentation/projet-vierge.yaml \&lt;br /&gt;
  --output /root/ajlsm-deploy/recettes/20261016/nouveau-projet.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Toutes les valeurs obligatoires seront demandées. Pour saisir de nouveau le projet MERCURE3, consulter mercure3-reference.yaml comme fiche de paramètres, sans lancer de déploiement.&lt;br /&gt;
&lt;br /&gt;
=== 5.3. Créer sans modèle ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml /root/ajlsm-deploy/recettes/20261016/nouveau-projet.yaml --new&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette commande est une alternative à la précédente : le chemin doit être inexistant. L’assistant pose les questions, y compris le nombre d’interfaces, sans reprendre implicitement les valeurs de MERCURE3.&lt;br /&gt;
&lt;br /&gt;
=== 5.4. Revoir un projet renseigné ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-yaml /etc/ajlsm/deploy/projets/mercure3.yaml --review \&lt;br /&gt;
  --output /root/ajlsm-deploy/recettes/20261016/mercure3-relecture.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Entrée conserve une valeur existante valide.&lt;br /&gt;
* ANNULER, Ctrl-C ou fin d’entrée abandonnent sans enregistrer.&lt;br /&gt;
* Tags et DNS sont saisis séparés par des virgules ; [] ou aucun signifie tags vides.&lt;br /&gt;
* Saisir auto ou null pour un VMID automatique.&lt;br /&gt;
* Après une incohérence, donner le chemin du champ à corriger ; ? affiche les chemins.&lt;br /&gt;
* Le résumé complet est présenté avant confirmation OUI/NON d’enregistrement.&lt;br /&gt;
&lt;br /&gt;
L’original reste intact, avec ses commentaires. La copie est réécrite en YAML, sans reprise des commentaires. Aucun fichier existant n’est écrasé. Si une destination existe, choisir un nouveau nom avec --output.&lt;br /&gt;
&lt;br /&gt;
=== 5.5. Préparatifs externes ===&lt;br /&gt;
&lt;br /&gt;
Avant une création, vérifier séparément la réservation des IP, les déclarations DNS, les règles/routes/NAT nécessaires dans OPNsense et l’inventaire ou les préparatifs Ansible. Ne pas inscrire de mots de passe dans le YAML ; conserver les secrets dans le dispositif prévu pour leur gestion.&lt;br /&gt;
&lt;br /&gt;
L’assistant actuel ne vérifie pas automatiquement ces services et ne marque pas un projet « prêt à déployer » sur cette seule base. Leur intégration reste à réaliser.&lt;br /&gt;
&lt;br /&gt;
Le contrôle Proxmox autonome examine notamment le modèle, ses ressources, le stockage et les bridges. Il concerne une nouvelle création et peut refuser un projet déjà déployé :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-check /chemin/vers/projet.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 6. Afficher le plan puis lancer le cycle ==&lt;br /&gt;
&lt;br /&gt;
=== 6.1. Plan sans exécution ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /chemin/vers/projet.yaml --plan&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le plan valide le YAML et affiche les commandes, sans exécuter les phases ni vérifier l’infrastructure. Il doit contenir les 11 étapes, toutes dans le dossier de recette.&lt;br /&gt;
&lt;br /&gt;
=== 6.2. Cycle réel pour une nouvelle VM ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /chemin/vers/projet.yaml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le lanceur exécute les phases réelles, sans simulation automatique. Il attend seulement les confirmations, les saisies nécessaires et la fin de chaque commande. Il s’arrête sur refus ou erreur. Il ne répond pas à la place de l’administrateur et ne capture pas les mots de passe.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! N° !! Étape !! Commande réelle !! Simulation facultative&lt;br /&gt;
|-&lt;br /&gt;
| 1 || Clonage || --clone || --dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Ressources || --configure-resources || --resources-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Premier démarrage isolé || --first-boot-apply || --first-boot-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Extension partition/LVM/ext4 || --root-grow-apply || --root-grow-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Identité système || --system-apply || --system-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Préparation Netplan || --network-apply || --network-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Activation réseau || --network-enable || --network-enable-dry-run&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Audit SSH || --ssh-audit || Aucune option dédiée&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Sécurisation SSH || --ssh-secure || Aucune option dédiée&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Mot de passe ajlsm || --password-ajlsm || Aucune option dédiée&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Certificat TLS interne || --tls-apply || Aucune option dédiée&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
L’extension racine est indispensable quand etendre_volume_racine vaut true. Agrandir le disque Proxmox ne suffit pas : la partition, le PV LVM, le LV et ext4 doivent aussi être étendus. Cette phase doit figurer après le premier démarrage, avant la personnalisation système. Avec false, la phase annonce sa désactivation.&lt;br /&gt;
&lt;br /&gt;
Le démarrage et la personnalisation se font réseau isolé. Netplan est préparé avant activation des liens. La phase d’activation contrôle le réseau et applique demarrage_auto.&lt;br /&gt;
&lt;br /&gt;
Le certificat TLS interne ne constitue pas, à lui seul, une configuration des applications du projet ou un certificat publiquement reconnu.&lt;br /&gt;
&lt;br /&gt;
=== 6.3. Mode manuel ===&lt;br /&gt;
&lt;br /&gt;
Chaque phase peut être lancée séparément avec ./ajlsm-deploy suivi du YAML et de son option. Après succès, le lot courant affiche deux lignes pour l’étape suivante : Simulation et Exécution. Si la simulation n’existe pas, il le signale. Aucune suggestion n’est exécutée automatiquement.&lt;br /&gt;
&lt;br /&gt;
Les simulations peuvent consulter l’invité et émettre des sondes ARP selon la phase : elles ne sont pas toutes des contrôles hors ligne. L’absence de réponse ARP ne remplace pas la réservation des adresses dans l’inventaire réseau.&lt;br /&gt;
&lt;br /&gt;
== 7. Erreur, annulation et reprise ==&lt;br /&gt;
&lt;br /&gt;
Conserver la sortie complète et diagnostiquer la phase fautive avant de reprendre. Une phase peut être partiellement effectuée ; le lanceur n’effectue ni suppression de VM ni restauration globale automatique.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./ajlsm-deploy-cycle /chemin/vers/projet.yaml --from extension-racine&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--from inclut l’étape indiquée et saute les précédentes à la demande de l’administrateur. Il ne certifie pas leur état. Les contrôles propres aux phases restent actifs. Le lanceur ne possède pas de journal persistant global de progression.&lt;br /&gt;
&lt;br /&gt;
Ne pas relancer le cycle depuis le clonage sur une VM existante pour terminer une étape. Ne pas relancer des étapes déjà terminées uniquement parce qu’une commande manuelle les suggère. Les suggestions suivent l’ordre théorique et ne constituent pas un inventaire de l’état de la VM.&lt;br /&gt;
&lt;br /&gt;
Codes de sortie : 0 succès, 1 annulation, 2 erreur. Le lanceur normalise les autres codes d’échec de ses sous-processus en erreur et ne poursuit pas.&lt;br /&gt;
&lt;br /&gt;
== 8. Vérifications finales ==&lt;br /&gt;
&lt;br /&gt;
Sur Saturne3, avec le VMID réellement annoncé au clonage :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
qm list&lt;br /&gt;
qm status VMID&lt;br /&gt;
qm config VMID&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remplacer VMID par l’identifiant vérifié. Contrôler le nom, les CPU, la RAM, le disque, les liens réseau et onboot selon le YAML.&lt;br /&gt;
&lt;br /&gt;
Depuis Saturne3, ouvrir la connexion et attendre l’invite de la VM :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh ajlsm@10.0.0.43&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dans MERCURE3, saisir sudo -i, attendre l’authentification et l’invite root, puis :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
hostname&lt;br /&gt;
lsblk&lt;br /&gt;
df -hT /&lt;br /&gt;
ip -br addr&lt;br /&gt;
ip route&lt;br /&gt;
resolvectl status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Résultat vérifié pendant la recette : hostname mercure3.ajlsm.com, racine ext4 97 Gio. Les tailles disponibles évoluent avec l’utilisation. Les commandes SSH et TLS du cycle vérifient leurs propres résultats ; compléter par les tests d’accès attendus dans le réseau cible.&lt;br /&gt;
&lt;br /&gt;
== 9. Reconstruire MERCURE3 ultérieurement ==&lt;br /&gt;
&lt;br /&gt;
# Conserver le fichier mercure3-reference.yaml, le lot de scripts validé et l’identification du modèle utilisé.&lt;br /&gt;
# Comparer la référence au YAML effectivement utilisé avant reconstruction ; actualiser les changements d’infrastructure.&lt;br /&gt;
# Identifier et sauvegarder les données à conserver : le YAML n’est pas une sauvegarde de VM.&lt;br /&gt;
# Vérifier explicitement l’identité de l’ancienne VM et traiter séparément son arrêt et sa suppression volontaire. Le cycle ne détruit jamais automatiquement une VM existante.&lt;br /&gt;
# Contrôler DNS, OPNsense, Ansible et les réservations d’IP. Ne pas laisser deux VM actives avec les mêmes adresses.&lt;br /&gt;
# Valider la référence avec --check, afficher le --plan, puis lancer le cycle sur la référence après libération de la cible.&lt;br /&gt;
# Relever le nouveau VMID et effectuer les vérifications finales.&lt;br /&gt;
&lt;br /&gt;
On retrouve ainsi les paramètres de la VM, sans chercher à reproduire ses anciennes identités techniques.&lt;br /&gt;
&lt;br /&gt;
== 10. Suites prévues ==&lt;br /&gt;
&lt;br /&gt;
Prévoir les paramètres NFS, sites Apache2, Pleade, Drupal et Matomo dans le même YAML lorsque leurs exigences seront définies. Modifier ensemble le schéma, l’assistant, les modèles, les précontrôles, les phases et leur documentation. Documenter les références aux secrets plutôt que leurs valeurs.&lt;br /&gt;
&lt;br /&gt;
L’intégration des contrôles DNS, OPNsense et Ansible précédera une déclaration automatisée de disponibilité du projet. Le modèle actuel ne contient pas encore ces nouvelles sections.&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=EOLE3_%E2%80%94_Acc%C3%A8s,_s%C3%A9curit%C3%A9_et_pare-feu&amp;diff=6489</id>
		<title>EOLE3 — Accès, sécurité et pare-feu</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=EOLE3_%E2%80%94_Acc%C3%A8s,_s%C3%A9curit%C3%A9_et_pare-feu&amp;diff=6489"/>
		<updated>2026-10-16T12:37:39Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= EOLE3 — Accès, sécurité et pare-feu =&lt;br /&gt;
Voir aussi [[Eole3_–_Checklist_mensuelle_de_sécurité]] : &lt;br /&gt;
&lt;br /&gt;
== 1. Objet du document ==&lt;br /&gt;
&lt;br /&gt;
Cette documentation décrit l&#039;organisation des accès et les mécanismes de sécurité du serveur EOLE3.&lt;br /&gt;
&lt;br /&gt;
Elle couvre notamment :&lt;br /&gt;
&lt;br /&gt;
* les comptes d&#039;administration ;&lt;br /&gt;
* les comptes techniques nominatifs ;&lt;br /&gt;
* les comptes clients SFTP ;&lt;br /&gt;
* les accès réseau publics et privés ;&lt;br /&gt;
* le pare-feu nftables ;&lt;br /&gt;
* Fail2ban ;&lt;br /&gt;
* les procédures de maintenance et de retour arrière.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Principe général :&#039;&#039;&#039; n&#039;exposer sur Internet que les services strictement nécessaires.&lt;br /&gt;
&lt;br /&gt;
Voir également :&lt;br /&gt;
&lt;br /&gt;
* [[EOLE3 — Administration, maintenance et flux de données]]&lt;br /&gt;
* [[EOLE3 — Checklist mensuelle de sécurité]]&lt;br /&gt;
&lt;br /&gt;
== 2. Architecture réseau ==&lt;br /&gt;
&lt;br /&gt;
=== 2.1 Interfaces ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Interface&lt;br /&gt;
! Adresse&lt;br /&gt;
! Utilisation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;enp9s0f0np0&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;51.178.110.230&amp;lt;/code&amp;gt;&lt;br /&gt;
| Réseau public OVH&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;enp9s0f1np1&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;192.168.123.202/24&amp;lt;/code&amp;gt;&lt;br /&gt;
| Réseau privé OVH vRack&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
EOLE3 dispose également d&#039;une connectivité IPv6 publique.&lt;br /&gt;
&lt;br /&gt;
Le réseau privé vRack est utilisé pour les échanges techniques entre serveurs, notamment les accès NFS et la supervision.&lt;br /&gt;
&lt;br /&gt;
=== 2.2 Politique de sécurité ===&lt;br /&gt;
&lt;br /&gt;
Les flux entrants sont refusés par défaut.&lt;br /&gt;
&lt;br /&gt;
Seuls sont autorisés :&lt;br /&gt;
&lt;br /&gt;
* les connexions déjà établies ;&lt;br /&gt;
* les communications locales ;&lt;br /&gt;
* les communications du réseau privé vRack ;&lt;br /&gt;
* les services publics explicitement autorisés ;&lt;br /&gt;
* les connexions SSH provenant des adresses administratives autorisées ;&lt;br /&gt;
* les protocoles nécessaires au fonctionnement réseau, notamment ICMP et ICMPv6.&lt;br /&gt;
&lt;br /&gt;
Les flux sortants ne sont pas filtrés par la configuration AJLSM actuelle.&lt;br /&gt;
&lt;br /&gt;
== 3. Politique des accès ==&lt;br /&gt;
&lt;br /&gt;
Les comptes sont répartis en quatre catégories :&lt;br /&gt;
&lt;br /&gt;
# compte système root ;&lt;br /&gt;
# compte d&#039;administration ubuntu ;&lt;br /&gt;
# comptes techniques nominatifs ;&lt;br /&gt;
# comptes clients SFTP.&lt;br /&gt;
&lt;br /&gt;
Cette séparation évite de mélanger les usages d&#039;administration, de maintenance et de transfert de fichiers.&lt;br /&gt;
&lt;br /&gt;
=== 3.1 Compte root ===&lt;br /&gt;
&lt;br /&gt;
Le compte &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; dispose de tous les privilèges système.&lt;br /&gt;
&lt;br /&gt;
Il est utilisé pour :&lt;br /&gt;
&lt;br /&gt;
* l&#039;administration du système ;&lt;br /&gt;
* la gestion ZFS ;&lt;br /&gt;
* les modifications de configuration ;&lt;br /&gt;
* les opérations de migration ;&lt;br /&gt;
* la maintenance et le dépannage ;&lt;br /&gt;
* la gestion des droits et propriétaires ;&lt;br /&gt;
* les opérations critiques sur les données clients.&lt;br /&gt;
&lt;br /&gt;
Son utilisation doit rester réservée aux opérations nécessitant réellement des privilèges administratifs.&lt;br /&gt;
&lt;br /&gt;
=== 3.2 Compte ubuntu ===&lt;br /&gt;
&lt;br /&gt;
Le compte &amp;lt;code&amp;gt;ubuntu&amp;lt;/code&amp;gt; constitue un point d&#039;entrée pour l&#039;administration distante.&lt;br /&gt;
&lt;br /&gt;
Il permet notamment :&lt;br /&gt;
&lt;br /&gt;
* la connexion SSH ;&lt;br /&gt;
* l&#039;utilisation de &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; ;&lt;br /&gt;
* les opérations courantes d&#039;administration.&lt;br /&gt;
&lt;br /&gt;
Il ne doit pas être utilisé comme compte client ou compte de dépôt.&lt;br /&gt;
&lt;br /&gt;
=== 3.3 Comptes techniques nominatifs ===&lt;br /&gt;
&lt;br /&gt;
Les comptes techniques sont individuels.&lt;br /&gt;
&lt;br /&gt;
Principes :&lt;br /&gt;
&lt;br /&gt;
* un compte par personne ;&lt;br /&gt;
* authentification par clé SSH ;&lt;br /&gt;
* droits attribués selon les besoins ;&lt;br /&gt;
* utilisation de &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; lorsque nécessaire ;&lt;br /&gt;
* traçabilité des interventions.&lt;br /&gt;
&lt;br /&gt;
Les comptes nominatifs ne doivent pas être partagés.&lt;br /&gt;
&lt;br /&gt;
=== 3.4 Comptes clients SFTP ===&lt;br /&gt;
&lt;br /&gt;
Les comptes clients servent aux dépôts et récupérations de fichiers.&lt;br /&gt;
&lt;br /&gt;
Exemple : &amp;lt;code&amp;gt;ad53&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ils sont associés à la logique métier Pleade et au confinement SFTP.&lt;br /&gt;
&lt;br /&gt;
La configuration OpenSSH documentée utilise notamment :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;apache&amp;quot;&amp;gt;&lt;br /&gt;
Match Group eole3-sftp&lt;br /&gt;
    ChrootDirectory %h&lt;br /&gt;
    ForceCommand internal-sftp -P setstat,fsetstat&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les restrictions complémentaires de transfert et de tunnel doivent être vérifiées dans la configuration SSH effective.&lt;br /&gt;
&lt;br /&gt;
Les comptes clients concernés :&lt;br /&gt;
&lt;br /&gt;
* ne disposent pas d&#039;un shell interactif ;&lt;br /&gt;
* sont confinés dans leur environnement ;&lt;br /&gt;
* ne peuvent pas accéder librement aux données des autres clients ;&lt;br /&gt;
* restent soumis aux permissions Unix.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; ces comptes SFTP OpenSSH ne doivent pas être confondus avec les utilisateurs gérés par le service SFTPGo sur le port 2022.&lt;br /&gt;
&lt;br /&gt;
=== 3.5 Permissions des données ===&lt;br /&gt;
&lt;br /&gt;
Les permissions d&#039;écriture sont définies par les droits Unix et les ACL éventuelles.&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;organisation documentée, les zones de travail comprennent notamment :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/data/pleade&lt;br /&gt;
/data/projets&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les répertoires suivants ne doivent pas devenir librement accessibles en écriture :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/data&lt;br /&gt;
/data/data-private&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les droits réels doivent être contrôlés avant toute modification.&lt;br /&gt;
&lt;br /&gt;
== 4. Pare-feu nftables ==&lt;br /&gt;
&lt;br /&gt;
=== 4.1 Solution retenue ===&lt;br /&gt;
&lt;br /&gt;
EOLE3 utilise nftables pour le filtrage réseau.&lt;br /&gt;
&lt;br /&gt;
Le pare-feu AJLSM est indépendant de Fail2ban.&lt;br /&gt;
&lt;br /&gt;
Il utilise exclusivement :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
table inet ajlsm_eole3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fail2ban conserve sa propre table :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
table inet f2b-table&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ne jamais utiliser &amp;lt;code&amp;gt;flush ruleset&amp;lt;/code&amp;gt; pour administrer le pare-feu AJLSM.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Cette commande pourrait supprimer les règles de Fail2ban.&lt;br /&gt;
&lt;br /&gt;
Le service standard &amp;lt;code&amp;gt;nftables.service&amp;lt;/code&amp;gt; n&#039;est pas utilisé pour charger la configuration AJLSM.&lt;br /&gt;
&lt;br /&gt;
=== 4.2 Fichiers de configuration ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Fichier&lt;br /&gt;
! Fonction&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/etc/nftables/ajlsm-eole3.nft&amp;lt;/code&amp;gt;&lt;br /&gt;
| Configuration principale du pare-feu&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/etc/nftables/ajlsm-eole3-reload.nft&amp;lt;/code&amp;gt;&lt;br /&gt;
| Rechargement atomique des règles&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/etc/systemd/system/ajlsm-firewall.service&amp;lt;/code&amp;gt;&lt;br /&gt;
| Service systemd dédié&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/root/ajlsm-eole3.nft&amp;lt;/code&amp;gt;&lt;br /&gt;
| Copie de travail historique&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
La configuration de référence est celle située dans &amp;lt;code&amp;gt;/etc/nftables/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== 4.3 Ports publics autorisés ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Port&lt;br /&gt;
! Protocole&lt;br /&gt;
! Service&lt;br /&gt;
! Origine autorisée&lt;br /&gt;
|-&lt;br /&gt;
| 80&lt;br /&gt;
| TCP&lt;br /&gt;
| Apache HTTP&lt;br /&gt;
| Internet&lt;br /&gt;
|-&lt;br /&gt;
| 443&lt;br /&gt;
| TCP&lt;br /&gt;
| Apache HTTPS&lt;br /&gt;
| Internet&lt;br /&gt;
|-&lt;br /&gt;
| 2022&lt;br /&gt;
| TCP&lt;br /&gt;
| SFTPGo&lt;br /&gt;
| Internet&lt;br /&gt;
|-&lt;br /&gt;
| 22&lt;br /&gt;
| TCP / IPv4&lt;br /&gt;
| SSH administration&lt;br /&gt;
| Adresses administratives autorisées&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 4.4 Adresses administratives autorisées ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Adresse IPv4&lt;br /&gt;
! Usage&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;109.190.129.96&amp;lt;/code&amp;gt;&lt;br /&gt;
| Bureau AJLSM&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;82.66.151.165&amp;lt;/code&amp;gt;&lt;br /&gt;
| Domicile&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Toute modification de ces adresses nécessite une mise à jour du fichier nftables.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ne jamais remplacer une adresse administrative sans avoir vérifié la possibilité de conserver un accès au serveur.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== 4.5 Ports interdits depuis Internet ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Port&lt;br /&gt;
! Service&lt;br /&gt;
! Politique&lt;br /&gt;
|-&lt;br /&gt;
| 111&lt;br /&gt;
| RPC&lt;br /&gt;
| Réseau privé uniquement&lt;br /&gt;
|-&lt;br /&gt;
| 2049&lt;br /&gt;
| NFS&lt;br /&gt;
| Réseau privé uniquement&lt;br /&gt;
|-&lt;br /&gt;
| 9001&lt;br /&gt;
| Lighttpd&lt;br /&gt;
| Réseau privé uniquement&lt;br /&gt;
|-&lt;br /&gt;
| 9090&lt;br /&gt;
| Cockpit&lt;br /&gt;
| Non accessible publiquement&lt;br /&gt;
|-&lt;br /&gt;
| 4330&lt;br /&gt;
| PCP&lt;br /&gt;
| Non accessible publiquement&lt;br /&gt;
|-&lt;br /&gt;
| 44321–44323&lt;br /&gt;
| PCP&lt;br /&gt;
| Non accessibles publiquement&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le pare-feu autorise les communications provenant du réseau privé &amp;lt;code&amp;gt;192.168.123.0/24&amp;lt;/code&amp;gt; lorsqu&#039;elles arrivent par l&#039;interface vRack.&lt;br /&gt;
&lt;br /&gt;
=== 4.6 Configuration nftables ===&lt;br /&gt;
&lt;br /&gt;
Le fichier principal est :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/etc/nftables/ajlsm-eole3.nft&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Configuration validée lors des tests du 16 octobre 2026 :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;nft&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/sbin/nft -f&lt;br /&gt;
&lt;br /&gt;
table inet ajlsm_eole3 {&lt;br /&gt;
&lt;br /&gt;
    define WAN = &amp;quot;enp9s0f0np0&amp;quot;&lt;br /&gt;
    define VRACK = &amp;quot;enp9s0f1np1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    define ADMIN_IPS = {&lt;br /&gt;
        109.190.129.96,&lt;br /&gt;
        82.66.151.165&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    chain input {&lt;br /&gt;
        type filter hook input priority filter;&lt;br /&gt;
        policy drop;&lt;br /&gt;
&lt;br /&gt;
        ct state established,related accept&lt;br /&gt;
        ct state invalid drop&lt;br /&gt;
&lt;br /&gt;
        iifname &amp;quot;lo&amp;quot; accept&lt;br /&gt;
&lt;br /&gt;
        iifname $VRACK ip saddr 192.168.123.0/24 accept&lt;br /&gt;
&lt;br /&gt;
        iifname $WAN ip protocol udp \&lt;br /&gt;
            udp sport 67 udp dport 68 accept&lt;br /&gt;
&lt;br /&gt;
        ip protocol icmp accept&lt;br /&gt;
        meta l4proto ipv6-icmp accept&lt;br /&gt;
&lt;br /&gt;
        iifname $WAN tcp dport { 80, 443 } accept&lt;br /&gt;
&lt;br /&gt;
        iifname $WAN tcp dport 2022 accept&lt;br /&gt;
&lt;br /&gt;
        iifname $WAN ip saddr $ADMIN_IPS tcp dport 22 accept&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette configuration applique une politique de refus par défaut aux connexions entrantes.&lt;br /&gt;
&lt;br /&gt;
Elle n&#039;ajoute pas de règles aux chaînes &amp;lt;code&amp;gt;forward&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;output&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== 4.7 Rechargement atomique ===&lt;br /&gt;
&lt;br /&gt;
Le fichier :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/etc/nftables/ajlsm-eole3-reload.nft&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
contient :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;nft&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/sbin/nft -f&lt;br /&gt;
&lt;br /&gt;
destroy table inet ajlsm_eole3&lt;br /&gt;
include &amp;quot;/etc/nftables/ajlsm-eole3.nft&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;instruction &amp;lt;code&amp;gt;destroy&amp;lt;/code&amp;gt; et le chargement de la nouvelle table sont exécutés dans une même transaction nftables.&lt;br /&gt;
&lt;br /&gt;
Le rechargement ne modifie pas la table Fail2ban.&lt;br /&gt;
&lt;br /&gt;
=== 4.8 Service systemd ===&lt;br /&gt;
&lt;br /&gt;
Le pare-feu est géré par :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ajlsm-firewall.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Commandes principales :&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;État :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl status ajlsm-firewall.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Démarrage :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl start ajlsm-firewall.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Arrêt :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl stop ajlsm-firewall.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Rechargement :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl reload ajlsm-firewall.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Activation au démarrage :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl enable ajlsm-firewall.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Désactivation au démarrage :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl disable ajlsm-firewall.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; &amp;lt;code&amp;gt;enable&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;disable&amp;lt;/code&amp;gt; modifient uniquement le comportement au démarrage. Ils ne démarrent ni n&#039;arrêtent immédiatement le pare-feu.&lt;br /&gt;
&lt;br /&gt;
=== 4.9 Vérifications ===&lt;br /&gt;
&lt;br /&gt;
Lister les tables :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nft list tables&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Avec le pare-feu actif, les tables attendues sont :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
table inet f2b-table&lt;br /&gt;
table inet ajlsm_eole3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Afficher les règles AJLSM :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nft list table inet ajlsm_eole3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier la syntaxe avant toute modification :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nft -c -f /etc/nftables/ajlsm-eole3-reload.nft&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier le service :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl is-active ajlsm-firewall.service&lt;br /&gt;
systemctl is-enabled ajlsm-firewall.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 5. Procédure de modification du pare-feu ==&lt;br /&gt;
&lt;br /&gt;
=== 5.1 Précautions obligatoires ===&lt;br /&gt;
&lt;br /&gt;
Avant toute modification :&lt;br /&gt;
&lt;br /&gt;
# conserver une session SSH administrative ouverte ;&lt;br /&gt;
# disposer d&#039;un accès de secours au serveur ;&lt;br /&gt;
# vérifier les adresses administratives autorisées ;&lt;br /&gt;
# sauvegarder la configuration précédente ;&lt;br /&gt;
# vérifier la syntaxe ;&lt;br /&gt;
# programmer un retour arrière automatique ;&lt;br /&gt;
# tester les services après modification.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ne jamais modifier les règles de filtrage à distance sans possibilité de retour arrière.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== 5.2 Sauvegarder la configuration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cp -a /etc/nftables/ajlsm-eole3.nft \&lt;br /&gt;
  /etc/nftables/ajlsm-eole3.nft.bak&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pour les interventions successives, utiliser de préférence des sauvegardes horodatées.&lt;br /&gt;
&lt;br /&gt;
=== 5.3 Vérifier les règles ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nft -c -f /etc/nftables/ajlsm-eole3-reload.nft&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette commande ne modifie pas le pare-feu actif.&lt;br /&gt;
&lt;br /&gt;
=== 5.4 Programmer un retour arrière ===&lt;br /&gt;
&lt;br /&gt;
Exemple : arrêt automatique du service après 15 minutes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemd-run \&lt;br /&gt;
  --unit=ajlsm-firewall-rollback \&lt;br /&gt;
  --on-active=15min \&lt;br /&gt;
  /usr/bin/systemctl stop ajlsm-firewall.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérification :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl list-timers --all | grep ajlsm-firewall-rollback&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Attention : un retour arrière qui arrête uniquement le service ne restaure pas automatiquement une ancienne configuration.&lt;br /&gt;
&lt;br /&gt;
Pour une modification de règles, prévoir également la restauration du fichier précédent si nécessaire.&lt;br /&gt;
&lt;br /&gt;
=== 5.5 Appliquer les modifications ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl reload ajlsm-firewall.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puis :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl status ajlsm-firewall.service --no-pager&lt;br /&gt;
nft list tables&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5.6 Vérifier les accès ===&lt;br /&gt;
&lt;br /&gt;
Tester notamment :&lt;br /&gt;
&lt;br /&gt;
* une nouvelle connexion SSH depuis une adresse administrative ;&lt;br /&gt;
* les accès HTTP et HTTPS ;&lt;br /&gt;
* SFTPGo ;&lt;br /&gt;
* les échanges NFS sur le vRack ;&lt;br /&gt;
* la supervision Centreon ;&lt;br /&gt;
* le blocage des ports internes depuis une connexion extérieure.&lt;br /&gt;
&lt;br /&gt;
== 6. Tests de sécurité réalisés le 16 octobre 2026 ==&lt;br /&gt;
&lt;br /&gt;
=== 6.1 Origine du test ===&lt;br /&gt;
&lt;br /&gt;
Les tests ont été réalisés depuis un Mac connecté au partage de connexion mobile d&#039;un iPhone.&lt;br /&gt;
&lt;br /&gt;
Adresse IPv4 publique utilisée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
176.135.13.221&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette adresse n&#039;appartient pas à la liste des adresses administratives autorisées.&lt;br /&gt;
&lt;br /&gt;
=== 6.2 Résultats ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Port&lt;br /&gt;
! Résultat observé&lt;br /&gt;
! Conforme&lt;br /&gt;
|-&lt;br /&gt;
| 22&lt;br /&gt;
| Bloqué&lt;br /&gt;
| Oui&lt;br /&gt;
|-&lt;br /&gt;
| 80&lt;br /&gt;
| Accessible&lt;br /&gt;
| Oui&lt;br /&gt;
|-&lt;br /&gt;
| 443&lt;br /&gt;
| Accessible&lt;br /&gt;
| Oui&lt;br /&gt;
|-&lt;br /&gt;
| 2022&lt;br /&gt;
| Accessible&lt;br /&gt;
| Oui&lt;br /&gt;
|-&lt;br /&gt;
| 111&lt;br /&gt;
| Bloqué&lt;br /&gt;
| Oui&lt;br /&gt;
|-&lt;br /&gt;
| 2049&lt;br /&gt;
| Bloqué&lt;br /&gt;
| Oui&lt;br /&gt;
|-&lt;br /&gt;
| 9001&lt;br /&gt;
| Bloqué&lt;br /&gt;
| Oui&lt;br /&gt;
|-&lt;br /&gt;
| 9090&lt;br /&gt;
| Bloqué&lt;br /&gt;
| Oui&lt;br /&gt;
|-&lt;br /&gt;
| 4330&lt;br /&gt;
| Bloqué&lt;br /&gt;
| Oui&lt;br /&gt;
|-&lt;br /&gt;
| 44321–44323&lt;br /&gt;
| Bloqués&lt;br /&gt;
| Oui&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les résultats confirment le comportement attendu des règles IPv4 pour les ports TCP testés.&lt;br /&gt;
&lt;br /&gt;
=== 6.3 Tests internes ===&lt;br /&gt;
&lt;br /&gt;
Les vérifications précédentes ont confirmé :&lt;br /&gt;
&lt;br /&gt;
* les accès NFS depuis les serveurs du vRack ;&lt;br /&gt;
* le fonctionnement de Lighttpd ;&lt;br /&gt;
* le fonctionnement de la supervision Centreon ;&lt;br /&gt;
* les accès publics Apache et SFTPGo ;&lt;br /&gt;
* l&#039;accès SSH depuis le bureau.&lt;br /&gt;
&lt;br /&gt;
=== 6.4 Limites des tests ===&lt;br /&gt;
&lt;br /&gt;
Les tests extérieurs ont principalement porté sur IPv4 et TCP.&lt;br /&gt;
&lt;br /&gt;
Ils ne constituent pas un audit exhaustif de l&#039;exposition IPv6, des services UDP ou de la configuration applicative.&lt;br /&gt;
&lt;br /&gt;
Ces points doivent faire l&#039;objet de contrôles complémentaires.&lt;br /&gt;
&lt;br /&gt;
== 7. Fail2ban ==&lt;br /&gt;
&lt;br /&gt;
=== 7.1 Principe ===&lt;br /&gt;
&lt;br /&gt;
Fail2ban complète le pare-feu en bloquant temporairement certaines adresses IP à partir des événements détectés dans les journaux.&lt;br /&gt;
&lt;br /&gt;
Il ne remplace pas la politique de filtrage nftables.&lt;br /&gt;
&lt;br /&gt;
Les règles Fail2ban sont gérées indépendamment dans :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
table inet f2b-table&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 7.2 Vérification ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl status fail2ban&lt;br /&gt;
fail2ban-client status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérification de la jail SSH :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
fail2ban-client status sshd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les autres jails doivent être contrôlées selon la configuration réellement active.&lt;br /&gt;
&lt;br /&gt;
Ne pas considérer qu&#039;une jail SFTPGo ou Cockpit existe sans l&#039;avoir vérifié.&lt;br /&gt;
&lt;br /&gt;
=== 7.3 Précautions ===&lt;br /&gt;
&lt;br /&gt;
* Ne pas supprimer la table Fail2ban.&lt;br /&gt;
* Ne pas utiliser &amp;lt;code&amp;gt;flush ruleset&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Vérifier les exclusions d&#039;adresses administratives.&lt;br /&gt;
* Contrôler régulièrement les bannissements.&lt;br /&gt;
* Vérifier les journaux en cas d&#039;activité inhabituelle.&lt;br /&gt;
&lt;br /&gt;
== 8. SSH ==&lt;br /&gt;
&lt;br /&gt;
=== 8.1 Politique réseau ===&lt;br /&gt;
&lt;br /&gt;
Le port SSH 22 est accessible depuis les adresses administratives autorisées.&lt;br /&gt;
&lt;br /&gt;
Il est bloqué depuis les autres adresses publiques IPv4.&lt;br /&gt;
&lt;br /&gt;
Le pare-feu ne prévoit pas d&#039;ouverture publique SSH en IPv6.&lt;br /&gt;
&lt;br /&gt;
=== 8.2 Authentification ===&lt;br /&gt;
&lt;br /&gt;
La configuration d&#039;authentification SSH doit être contrôlée séparément.&lt;br /&gt;
&lt;br /&gt;
Commandes :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sshd -T | grep -E \&lt;br /&gt;
  &#039;^(port|permitrootlogin|passwordauthentication|kbdinteractiveauthentication|pubkeyauthentication) &#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les restrictions par groupe doivent également être vérifiées dans les fichiers de configuration SSH.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; le filtrage réseau et l&#039;authentification SSH sont deux mécanismes distincts.&lt;br /&gt;
&lt;br /&gt;
== 9. SFTPGo ==&lt;br /&gt;
&lt;br /&gt;
SFTPGo est accessible publiquement sur le port TCP 2022.&lt;br /&gt;
&lt;br /&gt;
Son exposition est volontaire pour permettre les transferts clients.&lt;br /&gt;
&lt;br /&gt;
La sécurité repose notamment sur :&lt;br /&gt;
&lt;br /&gt;
* l&#039;authentification des utilisateurs ;&lt;br /&gt;
* les permissions des comptes ;&lt;br /&gt;
* la limitation des accès aux données ;&lt;br /&gt;
* la journalisation ;&lt;br /&gt;
* les éventuelles protections Fail2ban effectivement configurées.&lt;br /&gt;
&lt;br /&gt;
Vérification :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl status sftpgo&lt;br /&gt;
journalctl -u sftpgo --since &amp;quot;24 hours ago&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les interfaces d&#039;administration de SFTPGo ne doivent pas être exposées publiquement sans justification et protection adaptées.&lt;br /&gt;
&lt;br /&gt;
== 10. NFS et vRack ==&lt;br /&gt;
&lt;br /&gt;
Les échanges NFS sont autorisés sur le réseau privé :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
192.168.123.0/24&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les ports NFS et RPC ne sont pas accessibles depuis Internet lorsque le pare-feu AJLSM est actif.&lt;br /&gt;
&lt;br /&gt;
Vérifications :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
exportfs -v&lt;br /&gt;
showmount -e localhost&lt;br /&gt;
ss -tulpen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les exports NFS doivent conserver leurs propres restrictions d&#039;accès.&lt;br /&gt;
&lt;br /&gt;
Le pare-feu ne remplace pas les contrôles définis dans la configuration NFS.&lt;br /&gt;
&lt;br /&gt;
== 11. Supervision Centreon ==&lt;br /&gt;
&lt;br /&gt;
La supervision d&#039;EOLE3 doit utiliser son adresse privée vRack :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
192.168.123.202&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette configuration permet de superviser les services internes sans ouvrir leurs ports sur Internet.&lt;br /&gt;
&lt;br /&gt;
Lors des tests du 16 octobre 2026, la supervision a été adaptée pour utiliser cette adresse.&lt;br /&gt;
&lt;br /&gt;
== 12. Tests réseau depuis l&#039;extérieur ==&lt;br /&gt;
&lt;br /&gt;
Pour tester réellement les restrictions Internet, il faut utiliser une connexion extérieure indépendante du bureau et des VPN.&lt;br /&gt;
&lt;br /&gt;
=== 12.1 Particularité du Mac AJLSM ===&lt;br /&gt;
&lt;br /&gt;
L&#039;adaptateur Ethernet USB du Mac utilise :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
en7&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le Wi-Fi utilise :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
en0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
macOS peut continuer à privilégier Ethernet même lorsque le partage de connexion de l&#039;iPhone est activé.&lt;br /&gt;
&lt;br /&gt;
=== 12.2 Procédure ===&lt;br /&gt;
&lt;br /&gt;
# Désactiver les VPN.&lt;br /&gt;
# Désactiver temporairement l&#039;adaptateur Ethernet &amp;lt;code&amp;gt;en7&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Connecter le Mac au partage de connexion de l&#039;iPhone.&lt;br /&gt;
# Vérifier la route et l&#039;adresse publique.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
route -n get 1.1.1.1&lt;br /&gt;
curl -4 https://api.ipify.org&lt;br /&gt;
echo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;interface attendue est &amp;lt;code&amp;gt;en0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
L&#039;adresse publique doit être différente de celle du bureau.&lt;br /&gt;
&lt;br /&gt;
=== 12.3 Tester les ports ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for port in 22 80 443 2022 111 2049 9001 9090 4330 44321 44322 44323; do&lt;br /&gt;
    nc -vz -G 3 51.178.110.230 &amp;quot;$port&amp;quot; 2&amp;gt;&amp;amp;1&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Après les tests, réactiver Ethernet.&lt;br /&gt;
&lt;br /&gt;
== 13. Contrôles après redémarrage ==&lt;br /&gt;
&lt;br /&gt;
Après chaque redémarrage d&#039;EOLE3 :&lt;br /&gt;
&lt;br /&gt;
# vérifier le service AJLSM ;&lt;br /&gt;
# vérifier Fail2ban ;&lt;br /&gt;
# contrôler les tables nftables ;&lt;br /&gt;
# tester une nouvelle connexion SSH ;&lt;br /&gt;
# vérifier Apache et SFTPGo ;&lt;br /&gt;
# vérifier les échanges NFS ;&lt;br /&gt;
# contrôler Centreon.&lt;br /&gt;
&lt;br /&gt;
Commandes :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl is-active ajlsm-firewall.service&lt;br /&gt;
systemctl is-enabled ajlsm-firewall.service&lt;br /&gt;
&lt;br /&gt;
systemctl is-active fail2ban.service&lt;br /&gt;
&lt;br /&gt;
nft list tables&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 14. Règles à ne jamais oublier ==&lt;br /&gt;
&lt;br /&gt;
* Ne jamais utiliser &amp;lt;code&amp;gt;flush ruleset&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Ne jamais activer UFW en parallèle sans étude préalable.&lt;br /&gt;
* Ne jamais exposer NFS sur Internet.&lt;br /&gt;
* Ne jamais ouvrir Cockpit publiquement.&lt;br /&gt;
* Ne jamais modifier les adresses SSH autorisées sans accès de secours.&lt;br /&gt;
* Toujours conserver un mécanisme de retour arrière.&lt;br /&gt;
* Toujours tester depuis une véritable connexion extérieure.&lt;br /&gt;
* Toujours vérifier Fail2ban après une modification du pare-feu.&lt;br /&gt;
* Toujours vérifier les services internes après modification.&lt;br /&gt;
&lt;br /&gt;
== 15. Historique ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Date&lt;br /&gt;
! Intervention&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026&lt;br /&gt;
| Création et validation des règles nftables AJLSM&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026&lt;br /&gt;
| Validation des accès publics et des restrictions depuis le réseau mobile&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026&lt;br /&gt;
| Validation du démarrage, de l&#039;arrêt et du rechargement via systemd&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026&lt;br /&gt;
| Activation du service au démarrage ; vérification finale de persistance à confirmer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Catégorie:Eole3]]&lt;br /&gt;
[[Catégorie:Sécurité]]&lt;br /&gt;
[[Catégorie:Infrastructure]]&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=EOLE3_%E2%80%94_Acc%C3%A8s_et_s%C3%A9curit%C3%A9&amp;diff=6488</id>
		<title>EOLE3 — Accès et sécurité</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=EOLE3_%E2%80%94_Acc%C3%A8s_et_s%C3%A9curit%C3%A9&amp;diff=6488"/>
		<updated>2026-10-16T12:36:10Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Obsolète :&lt;br /&gt;
&lt;br /&gt;
Voir : &lt;br /&gt;
&lt;br /&gt;
# http://mw.ajlsm.com/wiki/Eole3_%E2%80%93_Checklist_mensuelle_de_s%C3%A9curit%C3%A9&lt;br /&gt;
# http://mw.ajlsm.com/wiki/EOLE3_%E2%80%94_Acc%C3%A8s,_s%C3%A9curit%C3%A9_et_pare-feu&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=S%C3%A9curit%C3%A9_Eole3_%E2%80%93_R%C3%A8gles_%C3%A0_ne_pas_oublier&amp;diff=6487</id>
		<title>Sécurité Eole3 – Règles à ne pas oublier</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=S%C3%A9curit%C3%A9_Eole3_%E2%80%93_R%C3%A8gles_%C3%A0_ne_pas_oublier&amp;diff=6487"/>
		<updated>2026-10-16T12:35:47Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Obsolète :&lt;br /&gt;
&lt;br /&gt;
Voir : &lt;br /&gt;
&lt;br /&gt;
# http://mw.ajlsm.com/wiki/Eole3_%E2%80%93_Checklist_mensuelle_de_s%C3%A9curit%C3%A9&lt;br /&gt;
# http://mw.ajlsm.com/wiki/EOLE3_%E2%80%94_Acc%C3%A8s,_s%C3%A9curit%C3%A9_et_pare-feu&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=S%C3%A9curit%C3%A9_Eole3_%E2%80%93_R%C3%A8gles_%C3%A0_ne_pas_oublier&amp;diff=6486</id>
		<title>Sécurité Eole3 – Règles à ne pas oublier</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=S%C3%A9curit%C3%A9_Eole3_%E2%80%93_R%C3%A8gles_%C3%A0_ne_pas_oublier&amp;diff=6486"/>
		<updated>2026-10-16T12:35:04Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Obsolète :&lt;br /&gt;
&lt;br /&gt;
Voir : http://mw.ajlsm.com/wiki/Eole3_%E2%80%93_Checklist_mensuelle_de_s%C3%A9curit%C3%A9&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=Eole3_%E2%80%93_Checklist_mensuelle_de_s%C3%A9curit%C3%A9&amp;diff=6485</id>
		<title>Eole3 – Checklist mensuelle de sécurité</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=Eole3_%E2%80%93_Checklist_mensuelle_de_s%C3%A9curit%C3%A9&amp;diff=6485"/>
		<updated>2026-10-16T12:34:39Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= EOLE3 — Checklist mensuelle de sécurité =&lt;br /&gt;
&lt;br /&gt;
{{Sommaire}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Serveur :&#039;&#039;&#039; EOLE3&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Système :&#039;&#039;&#039; Ubuntu 24.04 LTS&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Documentation de référence :&#039;&#039;&#039; [[EOLE3 — Accès, sécurité et pare-feu]]&lt;br /&gt;
&lt;br /&gt;
== 1. Vérification du pare-feu ==&lt;br /&gt;
&lt;br /&gt;
=== État du service ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl is-active ajlsm-firewall.service&lt;br /&gt;
systemctl is-enabled ajlsm-firewall.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Attendu :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
active&lt;br /&gt;
enabled&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tables nftables ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nft list tables&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Attendu :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
table inet f2b-table&lt;br /&gt;
table inet ajlsm_eole3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Contrôle des règles ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nft list table inet ajlsm_eole3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier :&lt;br /&gt;
&lt;br /&gt;
* politique INPUT DROP ;&lt;br /&gt;
* ports publics 80, 443 et 2022 ;&lt;br /&gt;
* SSH limité aux IP administratives ;&lt;br /&gt;
* réseau vRack autorisé ;&lt;br /&gt;
* absence d&#039;ouverture publique NFS, Cockpit ou Lighttpd.&lt;br /&gt;
&lt;br /&gt;
== 2. Vérification Fail2ban ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl status fail2ban --no-pager&lt;br /&gt;
fail2ban-client status&lt;br /&gt;
fail2ban-client status sshd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier :&lt;br /&gt;
&lt;br /&gt;
* service actif ;&lt;br /&gt;
* jails réellement chargées ;&lt;br /&gt;
* adresses bannies ;&lt;br /&gt;
* absence de bannissement administratif inattendu.&lt;br /&gt;
&lt;br /&gt;
== 3. Vérification SSH ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sshd -T | grep -E \&lt;br /&gt;
  &#039;^(port|permitrootlogin|passwordauthentication|kbdinteractiveauthentication|pubkeyauthentication) &#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Contrôler :&lt;br /&gt;
&lt;br /&gt;
* les méthodes d&#039;authentification ;&lt;br /&gt;
* les comptes administratifs ;&lt;br /&gt;
* les restrictions des comptes SFTP ;&lt;br /&gt;
* les nouvelles connexions depuis les adresses autorisées.&lt;br /&gt;
&lt;br /&gt;
== 4. Vérification des services ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl --failed&lt;br /&gt;
systemctl status ssh fail2ban sftpgo apache2 --no-pager&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Contrôler également les services NFS, Lighttpd et de supervision selon leur configuration effective.&lt;br /&gt;
&lt;br /&gt;
== 5. Vérification SFTPGo ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl status sftpgo --no-pager&lt;br /&gt;
journalctl -u sftpgo --since &amp;quot;1 month ago&amp;quot; --no-pager&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rechercher :&lt;br /&gt;
&lt;br /&gt;
* tentatives de connexion inhabituelles ;&lt;br /&gt;
* erreurs d&#039;authentification ;&lt;br /&gt;
* téléchargements anormalement volumineux ;&lt;br /&gt;
* comptes inutilisés ;&lt;br /&gt;
* activités suspectes.&lt;br /&gt;
&lt;br /&gt;
== 6. Vérification NFS ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
exportfs -v&lt;br /&gt;
showmount -e localhost&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier :&lt;br /&gt;
&lt;br /&gt;
* les clients autorisés ;&lt;br /&gt;
* les exports ;&lt;br /&gt;
* les droits d&#039;accès ;&lt;br /&gt;
* le fonctionnement des montages depuis le vRack.&lt;br /&gt;
&lt;br /&gt;
== 7. Vérification des ports en écoute ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ss -tulpen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comparer les services en écoute avec les règles nftables.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; un service peut écouter sur une adresse publique tout en étant bloqué par le pare-feu.&lt;br /&gt;
&lt;br /&gt;
Le contrôle des sockets ne remplace donc pas un test depuis Internet.&lt;br /&gt;
&lt;br /&gt;
== 8. Vérification des journaux ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
journalctl -p err -b --no-pager&lt;br /&gt;
journalctl -u ajlsm-firewall.service --since &amp;quot;1 month ago&amp;quot; --no-pager&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rechercher :&lt;br /&gt;
&lt;br /&gt;
* erreurs système répétées ;&lt;br /&gt;
* redémarrages inattendus ;&lt;br /&gt;
* échecs de chargement nftables ;&lt;br /&gt;
* anomalies réseau.&lt;br /&gt;
&lt;br /&gt;
== 9. Vérification ZFS ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
zpool status&lt;br /&gt;
zpool list&lt;br /&gt;
zfs list&lt;br /&gt;
df -h&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier :&lt;br /&gt;
&lt;br /&gt;
* état ONLINE ;&lt;br /&gt;
* absence d&#039;erreurs de lecture, écriture ou checksum ;&lt;br /&gt;
* capacité disponible ;&lt;br /&gt;
* résultats des scrubs.&lt;br /&gt;
&lt;br /&gt;
== 10. Vérification des ressources ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
free -h&lt;br /&gt;
uptime&lt;br /&gt;
df -h&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Contrôler :&lt;br /&gt;
&lt;br /&gt;
* mémoire disponible ;&lt;br /&gt;
* charge système ;&lt;br /&gt;
* occupation disque ;&lt;br /&gt;
* évolution des ressources par rapport aux contrôles précédents.&lt;br /&gt;
&lt;br /&gt;
== 11. Vérification des mises à jour ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt update&lt;br /&gt;
apt list --upgradable&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Analyser les mises à jour disponibles.&lt;br /&gt;
&lt;br /&gt;
Les mises à jour et redémarrages doivent être réalisés dans une fenêtre de maintenance adaptée.&lt;br /&gt;
&lt;br /&gt;
== 12. Vérification de la supervision ==&lt;br /&gt;
&lt;br /&gt;
Vérifier dans Centreon :&lt;br /&gt;
&lt;br /&gt;
* disponibilité d&#039;EOLE3 ;&lt;br /&gt;
* utilisation de l&#039;adresse vRack &amp;lt;code&amp;gt;192.168.123.202&amp;lt;/code&amp;gt; ;&lt;br /&gt;
* absence d&#039;alertes persistantes ;&lt;br /&gt;
* fonctionnement des contrôles de services et de ressources.&lt;br /&gt;
&lt;br /&gt;
== 13. Vérification des accès extérieurs ==&lt;br /&gt;
&lt;br /&gt;
Réaliser périodiquement un test depuis une connexion indépendante du bureau et des VPN.&lt;br /&gt;
&lt;br /&gt;
Ports publics attendus :&lt;br /&gt;
&lt;br /&gt;
* 80 ;&lt;br /&gt;
* 443 ;&lt;br /&gt;
* 2022.&lt;br /&gt;
&lt;br /&gt;
Ports devant être bloqués depuis une adresse non autorisée :&lt;br /&gt;
&lt;br /&gt;
* 22 ;&lt;br /&gt;
* 111 ;&lt;br /&gt;
* 2049 ;&lt;br /&gt;
* 9001 ;&lt;br /&gt;
* 9090 ;&lt;br /&gt;
* 4330 ;&lt;br /&gt;
* 44321 à 44323.&lt;br /&gt;
&lt;br /&gt;
Effectuer également un contrôle IPv6.&lt;br /&gt;
&lt;br /&gt;
== 14. Vérification des sauvegardes et du retour arrière ==&lt;br /&gt;
&lt;br /&gt;
Contrôler :&lt;br /&gt;
&lt;br /&gt;
* l&#039;état des sauvegardes ;&lt;br /&gt;
* les possibilités de restauration ;&lt;br /&gt;
* l&#039;accès administratif de secours ;&lt;br /&gt;
* la disponibilité des configurations précédentes ;&lt;br /&gt;
* la possibilité de désactiver le pare-feu AJLSM sans toucher à Fail2ban.&lt;br /&gt;
&lt;br /&gt;
== 15. Synthèse du contrôle ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Contrôle&lt;br /&gt;
! Résultat&lt;br /&gt;
! Observations&lt;br /&gt;
|-&lt;br /&gt;
| Pare-feu nftables&lt;br /&gt;
| À vérifier&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| Fail2ban&lt;br /&gt;
| À vérifier&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| SSH&lt;br /&gt;
| À vérifier&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| Apache / SFTPGo&lt;br /&gt;
| À vérifier&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| NFS / vRack&lt;br /&gt;
| À vérifier&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| Supervision Centreon&lt;br /&gt;
| À vérifier&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| ZFS&lt;br /&gt;
| À vérifier&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| Ressources système&lt;br /&gt;
| À vérifier&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| Mises à jour&lt;br /&gt;
| À vérifier&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| Sauvegardes&lt;br /&gt;
| À vérifier&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Catégorie:Eole3]]&lt;br /&gt;
[[Catégorie:Sécurité]]&lt;br /&gt;
[[Catégorie:Maintenance]]&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=EOLE3_%E2%80%94_Acc%C3%A8s,_s%C3%A9curit%C3%A9_et_pare-feu&amp;diff=6484</id>
		<title>EOLE3 — Accès, sécurité et pare-feu</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=EOLE3_%E2%80%94_Acc%C3%A8s,_s%C3%A9curit%C3%A9_et_pare-feu&amp;diff=6484"/>
		<updated>2026-10-16T12:33:46Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : Page créée avec « = EOLE3 — Accès, sécurité et pare-feu =  {{Sommaire}}  == 1. Objet du document ==  Cette documentation décrit l&amp;#039;organisation des accès et les mécanismes de sécuri... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= EOLE3 — Accès, sécurité et pare-feu =&lt;br /&gt;
&lt;br /&gt;
{{Sommaire}}&lt;br /&gt;
&lt;br /&gt;
== 1. Objet du document ==&lt;br /&gt;
&lt;br /&gt;
Cette documentation décrit l&#039;organisation des accès et les mécanismes de sécurité du serveur EOLE3.&lt;br /&gt;
&lt;br /&gt;
Elle couvre notamment :&lt;br /&gt;
&lt;br /&gt;
* les comptes d&#039;administration ;&lt;br /&gt;
* les comptes techniques nominatifs ;&lt;br /&gt;
* les comptes clients SFTP ;&lt;br /&gt;
* les accès réseau publics et privés ;&lt;br /&gt;
* le pare-feu nftables ;&lt;br /&gt;
* Fail2ban ;&lt;br /&gt;
* les procédures de maintenance et de retour arrière.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Principe général :&#039;&#039;&#039; n&#039;exposer sur Internet que les services strictement nécessaires.&lt;br /&gt;
&lt;br /&gt;
Voir également :&lt;br /&gt;
&lt;br /&gt;
* [[EOLE3 — Administration, maintenance et flux de données]]&lt;br /&gt;
* [[EOLE3 — Checklist mensuelle de sécurité]]&lt;br /&gt;
&lt;br /&gt;
== 2. Architecture réseau ==&lt;br /&gt;
&lt;br /&gt;
=== 2.1 Interfaces ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Interface&lt;br /&gt;
! Adresse&lt;br /&gt;
! Utilisation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;enp9s0f0np0&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;51.178.110.230&amp;lt;/code&amp;gt;&lt;br /&gt;
| Réseau public OVH&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;enp9s0f1np1&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;192.168.123.202/24&amp;lt;/code&amp;gt;&lt;br /&gt;
| Réseau privé OVH vRack&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
EOLE3 dispose également d&#039;une connectivité IPv6 publique.&lt;br /&gt;
&lt;br /&gt;
Le réseau privé vRack est utilisé pour les échanges techniques entre serveurs, notamment les accès NFS et la supervision.&lt;br /&gt;
&lt;br /&gt;
=== 2.2 Politique de sécurité ===&lt;br /&gt;
&lt;br /&gt;
Les flux entrants sont refusés par défaut.&lt;br /&gt;
&lt;br /&gt;
Seuls sont autorisés :&lt;br /&gt;
&lt;br /&gt;
* les connexions déjà établies ;&lt;br /&gt;
* les communications locales ;&lt;br /&gt;
* les communications du réseau privé vRack ;&lt;br /&gt;
* les services publics explicitement autorisés ;&lt;br /&gt;
* les connexions SSH provenant des adresses administratives autorisées ;&lt;br /&gt;
* les protocoles nécessaires au fonctionnement réseau, notamment ICMP et ICMPv6.&lt;br /&gt;
&lt;br /&gt;
Les flux sortants ne sont pas filtrés par la configuration AJLSM actuelle.&lt;br /&gt;
&lt;br /&gt;
== 3. Politique des accès ==&lt;br /&gt;
&lt;br /&gt;
Les comptes sont répartis en quatre catégories :&lt;br /&gt;
&lt;br /&gt;
# compte système root ;&lt;br /&gt;
# compte d&#039;administration ubuntu ;&lt;br /&gt;
# comptes techniques nominatifs ;&lt;br /&gt;
# comptes clients SFTP.&lt;br /&gt;
&lt;br /&gt;
Cette séparation évite de mélanger les usages d&#039;administration, de maintenance et de transfert de fichiers.&lt;br /&gt;
&lt;br /&gt;
=== 3.1 Compte root ===&lt;br /&gt;
&lt;br /&gt;
Le compte &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; dispose de tous les privilèges système.&lt;br /&gt;
&lt;br /&gt;
Il est utilisé pour :&lt;br /&gt;
&lt;br /&gt;
* l&#039;administration du système ;&lt;br /&gt;
* la gestion ZFS ;&lt;br /&gt;
* les modifications de configuration ;&lt;br /&gt;
* les opérations de migration ;&lt;br /&gt;
* la maintenance et le dépannage ;&lt;br /&gt;
* la gestion des droits et propriétaires ;&lt;br /&gt;
* les opérations critiques sur les données clients.&lt;br /&gt;
&lt;br /&gt;
Son utilisation doit rester réservée aux opérations nécessitant réellement des privilèges administratifs.&lt;br /&gt;
&lt;br /&gt;
=== 3.2 Compte ubuntu ===&lt;br /&gt;
&lt;br /&gt;
Le compte &amp;lt;code&amp;gt;ubuntu&amp;lt;/code&amp;gt; constitue un point d&#039;entrée pour l&#039;administration distante.&lt;br /&gt;
&lt;br /&gt;
Il permet notamment :&lt;br /&gt;
&lt;br /&gt;
* la connexion SSH ;&lt;br /&gt;
* l&#039;utilisation de &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; ;&lt;br /&gt;
* les opérations courantes d&#039;administration.&lt;br /&gt;
&lt;br /&gt;
Il ne doit pas être utilisé comme compte client ou compte de dépôt.&lt;br /&gt;
&lt;br /&gt;
=== 3.3 Comptes techniques nominatifs ===&lt;br /&gt;
&lt;br /&gt;
Les comptes techniques sont individuels.&lt;br /&gt;
&lt;br /&gt;
Principes :&lt;br /&gt;
&lt;br /&gt;
* un compte par personne ;&lt;br /&gt;
* authentification par clé SSH ;&lt;br /&gt;
* droits attribués selon les besoins ;&lt;br /&gt;
* utilisation de &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; lorsque nécessaire ;&lt;br /&gt;
* traçabilité des interventions.&lt;br /&gt;
&lt;br /&gt;
Les comptes nominatifs ne doivent pas être partagés.&lt;br /&gt;
&lt;br /&gt;
=== 3.4 Comptes clients SFTP ===&lt;br /&gt;
&lt;br /&gt;
Les comptes clients servent aux dépôts et récupérations de fichiers.&lt;br /&gt;
&lt;br /&gt;
Exemple : &amp;lt;code&amp;gt;ad53&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ils sont associés à la logique métier Pleade et au confinement SFTP.&lt;br /&gt;
&lt;br /&gt;
La configuration OpenSSH documentée utilise notamment :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;apache&amp;quot;&amp;gt;&lt;br /&gt;
Match Group eole3-sftp&lt;br /&gt;
    ChrootDirectory %h&lt;br /&gt;
    ForceCommand internal-sftp -P setstat,fsetstat&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les restrictions complémentaires de transfert et de tunnel doivent être vérifiées dans la configuration SSH effective.&lt;br /&gt;
&lt;br /&gt;
Les comptes clients concernés :&lt;br /&gt;
&lt;br /&gt;
* ne disposent pas d&#039;un shell interactif ;&lt;br /&gt;
* sont confinés dans leur environnement ;&lt;br /&gt;
* ne peuvent pas accéder librement aux données des autres clients ;&lt;br /&gt;
* restent soumis aux permissions Unix.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; ces comptes SFTP OpenSSH ne doivent pas être confondus avec les utilisateurs gérés par le service SFTPGo sur le port 2022.&lt;br /&gt;
&lt;br /&gt;
=== 3.5 Permissions des données ===&lt;br /&gt;
&lt;br /&gt;
Les permissions d&#039;écriture sont définies par les droits Unix et les ACL éventuelles.&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;organisation documentée, les zones de travail comprennent notamment :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/data/pleade&lt;br /&gt;
/data/projets&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les répertoires suivants ne doivent pas devenir librement accessibles en écriture :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
/data&lt;br /&gt;
/data/data-private&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les droits réels doivent être contrôlés avant toute modification.&lt;br /&gt;
&lt;br /&gt;
== 4. Pare-feu nftables ==&lt;br /&gt;
&lt;br /&gt;
=== 4.1 Solution retenue ===&lt;br /&gt;
&lt;br /&gt;
EOLE3 utilise nftables pour le filtrage réseau.&lt;br /&gt;
&lt;br /&gt;
Le pare-feu AJLSM est indépendant de Fail2ban.&lt;br /&gt;
&lt;br /&gt;
Il utilise exclusivement :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
table inet ajlsm_eole3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fail2ban conserve sa propre table :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
table inet f2b-table&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ne jamais utiliser &amp;lt;code&amp;gt;flush ruleset&amp;lt;/code&amp;gt; pour administrer le pare-feu AJLSM.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Cette commande pourrait supprimer les règles de Fail2ban.&lt;br /&gt;
&lt;br /&gt;
Le service standard &amp;lt;code&amp;gt;nftables.service&amp;lt;/code&amp;gt; n&#039;est pas utilisé pour charger la configuration AJLSM.&lt;br /&gt;
&lt;br /&gt;
=== 4.2 Fichiers de configuration ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Fichier&lt;br /&gt;
! Fonction&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/etc/nftables/ajlsm-eole3.nft&amp;lt;/code&amp;gt;&lt;br /&gt;
| Configuration principale du pare-feu&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/etc/nftables/ajlsm-eole3-reload.nft&amp;lt;/code&amp;gt;&lt;br /&gt;
| Rechargement atomique des règles&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/etc/systemd/system/ajlsm-firewall.service&amp;lt;/code&amp;gt;&lt;br /&gt;
| Service systemd dédié&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/root/ajlsm-eole3.nft&amp;lt;/code&amp;gt;&lt;br /&gt;
| Copie de travail historique&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
La configuration de référence est celle située dans &amp;lt;code&amp;gt;/etc/nftables/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== 4.3 Ports publics autorisés ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Port&lt;br /&gt;
! Protocole&lt;br /&gt;
! Service&lt;br /&gt;
! Origine autorisée&lt;br /&gt;
|-&lt;br /&gt;
| 80&lt;br /&gt;
| TCP&lt;br /&gt;
| Apache HTTP&lt;br /&gt;
| Internet&lt;br /&gt;
|-&lt;br /&gt;
| 443&lt;br /&gt;
| TCP&lt;br /&gt;
| Apache HTTPS&lt;br /&gt;
| Internet&lt;br /&gt;
|-&lt;br /&gt;
| 2022&lt;br /&gt;
| TCP&lt;br /&gt;
| SFTPGo&lt;br /&gt;
| Internet&lt;br /&gt;
|-&lt;br /&gt;
| 22&lt;br /&gt;
| TCP / IPv4&lt;br /&gt;
| SSH administration&lt;br /&gt;
| Adresses administratives autorisées&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 4.4 Adresses administratives autorisées ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Adresse IPv4&lt;br /&gt;
! Usage&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;109.190.129.96&amp;lt;/code&amp;gt;&lt;br /&gt;
| Bureau AJLSM&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;82.66.151.165&amp;lt;/code&amp;gt;&lt;br /&gt;
| Domicile&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Toute modification de ces adresses nécessite une mise à jour du fichier nftables.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ne jamais remplacer une adresse administrative sans avoir vérifié la possibilité de conserver un accès au serveur.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== 4.5 Ports interdits depuis Internet ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Port&lt;br /&gt;
! Service&lt;br /&gt;
! Politique&lt;br /&gt;
|-&lt;br /&gt;
| 111&lt;br /&gt;
| RPC&lt;br /&gt;
| Réseau privé uniquement&lt;br /&gt;
|-&lt;br /&gt;
| 2049&lt;br /&gt;
| NFS&lt;br /&gt;
| Réseau privé uniquement&lt;br /&gt;
|-&lt;br /&gt;
| 9001&lt;br /&gt;
| Lighttpd&lt;br /&gt;
| Réseau privé uniquement&lt;br /&gt;
|-&lt;br /&gt;
| 9090&lt;br /&gt;
| Cockpit&lt;br /&gt;
| Non accessible publiquement&lt;br /&gt;
|-&lt;br /&gt;
| 4330&lt;br /&gt;
| PCP&lt;br /&gt;
| Non accessible publiquement&lt;br /&gt;
|-&lt;br /&gt;
| 44321–44323&lt;br /&gt;
| PCP&lt;br /&gt;
| Non accessibles publiquement&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Le pare-feu autorise les communications provenant du réseau privé &amp;lt;code&amp;gt;192.168.123.0/24&amp;lt;/code&amp;gt; lorsqu&#039;elles arrivent par l&#039;interface vRack.&lt;br /&gt;
&lt;br /&gt;
=== 4.6 Configuration nftables ===&lt;br /&gt;
&lt;br /&gt;
Le fichier principal est :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/etc/nftables/ajlsm-eole3.nft&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Configuration validée lors des tests du 16 octobre 2026 :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;nft&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/sbin/nft -f&lt;br /&gt;
&lt;br /&gt;
table inet ajlsm_eole3 {&lt;br /&gt;
&lt;br /&gt;
    define WAN = &amp;quot;enp9s0f0np0&amp;quot;&lt;br /&gt;
    define VRACK = &amp;quot;enp9s0f1np1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    define ADMIN_IPS = {&lt;br /&gt;
        109.190.129.96,&lt;br /&gt;
        82.66.151.165&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    chain input {&lt;br /&gt;
        type filter hook input priority filter;&lt;br /&gt;
        policy drop;&lt;br /&gt;
&lt;br /&gt;
        ct state established,related accept&lt;br /&gt;
        ct state invalid drop&lt;br /&gt;
&lt;br /&gt;
        iifname &amp;quot;lo&amp;quot; accept&lt;br /&gt;
&lt;br /&gt;
        iifname $VRACK ip saddr 192.168.123.0/24 accept&lt;br /&gt;
&lt;br /&gt;
        iifname $WAN ip protocol udp \&lt;br /&gt;
            udp sport 67 udp dport 68 accept&lt;br /&gt;
&lt;br /&gt;
        ip protocol icmp accept&lt;br /&gt;
        meta l4proto ipv6-icmp accept&lt;br /&gt;
&lt;br /&gt;
        iifname $WAN tcp dport { 80, 443 } accept&lt;br /&gt;
&lt;br /&gt;
        iifname $WAN tcp dport 2022 accept&lt;br /&gt;
&lt;br /&gt;
        iifname $WAN ip saddr $ADMIN_IPS tcp dport 22 accept&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette configuration applique une politique de refus par défaut aux connexions entrantes.&lt;br /&gt;
&lt;br /&gt;
Elle n&#039;ajoute pas de règles aux chaînes &amp;lt;code&amp;gt;forward&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;output&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== 4.7 Rechargement atomique ===&lt;br /&gt;
&lt;br /&gt;
Le fichier :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/etc/nftables/ajlsm-eole3-reload.nft&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
contient :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;nft&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/sbin/nft -f&lt;br /&gt;
&lt;br /&gt;
destroy table inet ajlsm_eole3&lt;br /&gt;
include &amp;quot;/etc/nftables/ajlsm-eole3.nft&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;instruction &amp;lt;code&amp;gt;destroy&amp;lt;/code&amp;gt; et le chargement de la nouvelle table sont exécutés dans une même transaction nftables.&lt;br /&gt;
&lt;br /&gt;
Le rechargement ne modifie pas la table Fail2ban.&lt;br /&gt;
&lt;br /&gt;
=== 4.8 Service systemd ===&lt;br /&gt;
&lt;br /&gt;
Le pare-feu est géré par :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ajlsm-firewall.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Commandes principales :&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;État :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl status ajlsm-firewall.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Démarrage :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl start ajlsm-firewall.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Arrêt :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl stop ajlsm-firewall.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Rechargement :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl reload ajlsm-firewall.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Activation au démarrage :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl enable ajlsm-firewall.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Désactivation au démarrage :&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl disable ajlsm-firewall.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important :&#039;&#039;&#039; &amp;lt;code&amp;gt;enable&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;disable&amp;lt;/code&amp;gt; modifient uniquement le comportement au démarrage. Ils ne démarrent ni n&#039;arrêtent immédiatement le pare-feu.&lt;br /&gt;
&lt;br /&gt;
=== 4.9 Vérifications ===&lt;br /&gt;
&lt;br /&gt;
Lister les tables :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nft list tables&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Avec le pare-feu actif, les tables attendues sont :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
table inet f2b-table&lt;br /&gt;
table inet ajlsm_eole3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Afficher les règles AJLSM :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nft list table inet ajlsm_eole3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier la syntaxe avant toute modification :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nft -c -f /etc/nftables/ajlsm-eole3-reload.nft&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérifier le service :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl is-active ajlsm-firewall.service&lt;br /&gt;
systemctl is-enabled ajlsm-firewall.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 5. Procédure de modification du pare-feu ==&lt;br /&gt;
&lt;br /&gt;
=== 5.1 Précautions obligatoires ===&lt;br /&gt;
&lt;br /&gt;
Avant toute modification :&lt;br /&gt;
&lt;br /&gt;
# conserver une session SSH administrative ouverte ;&lt;br /&gt;
# disposer d&#039;un accès de secours au serveur ;&lt;br /&gt;
# vérifier les adresses administratives autorisées ;&lt;br /&gt;
# sauvegarder la configuration précédente ;&lt;br /&gt;
# vérifier la syntaxe ;&lt;br /&gt;
# programmer un retour arrière automatique ;&lt;br /&gt;
# tester les services après modification.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ne jamais modifier les règles de filtrage à distance sans possibilité de retour arrière.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== 5.2 Sauvegarder la configuration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cp -a /etc/nftables/ajlsm-eole3.nft \&lt;br /&gt;
  /etc/nftables/ajlsm-eole3.nft.bak&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pour les interventions successives, utiliser de préférence des sauvegardes horodatées.&lt;br /&gt;
&lt;br /&gt;
=== 5.3 Vérifier les règles ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nft -c -f /etc/nftables/ajlsm-eole3-reload.nft&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette commande ne modifie pas le pare-feu actif.&lt;br /&gt;
&lt;br /&gt;
=== 5.4 Programmer un retour arrière ===&lt;br /&gt;
&lt;br /&gt;
Exemple : arrêt automatique du service après 15 minutes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemd-run \&lt;br /&gt;
  --unit=ajlsm-firewall-rollback \&lt;br /&gt;
  --on-active=15min \&lt;br /&gt;
  /usr/bin/systemctl stop ajlsm-firewall.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérification :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl list-timers --all | grep ajlsm-firewall-rollback&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Attention : un retour arrière qui arrête uniquement le service ne restaure pas automatiquement une ancienne configuration.&lt;br /&gt;
&lt;br /&gt;
Pour une modification de règles, prévoir également la restauration du fichier précédent si nécessaire.&lt;br /&gt;
&lt;br /&gt;
=== 5.5 Appliquer les modifications ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl reload ajlsm-firewall.service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puis :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl status ajlsm-firewall.service --no-pager&lt;br /&gt;
nft list tables&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5.6 Vérifier les accès ===&lt;br /&gt;
&lt;br /&gt;
Tester notamment :&lt;br /&gt;
&lt;br /&gt;
* une nouvelle connexion SSH depuis une adresse administrative ;&lt;br /&gt;
* les accès HTTP et HTTPS ;&lt;br /&gt;
* SFTPGo ;&lt;br /&gt;
* les échanges NFS sur le vRack ;&lt;br /&gt;
* la supervision Centreon ;&lt;br /&gt;
* le blocage des ports internes depuis une connexion extérieure.&lt;br /&gt;
&lt;br /&gt;
== 6. Tests de sécurité réalisés le 16 octobre 2026 ==&lt;br /&gt;
&lt;br /&gt;
=== 6.1 Origine du test ===&lt;br /&gt;
&lt;br /&gt;
Les tests ont été réalisés depuis un Mac connecté au partage de connexion mobile d&#039;un iPhone.&lt;br /&gt;
&lt;br /&gt;
Adresse IPv4 publique utilisée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
176.135.13.221&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette adresse n&#039;appartient pas à la liste des adresses administratives autorisées.&lt;br /&gt;
&lt;br /&gt;
=== 6.2 Résultats ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Port&lt;br /&gt;
! Résultat observé&lt;br /&gt;
! Conforme&lt;br /&gt;
|-&lt;br /&gt;
| 22&lt;br /&gt;
| Bloqué&lt;br /&gt;
| Oui&lt;br /&gt;
|-&lt;br /&gt;
| 80&lt;br /&gt;
| Accessible&lt;br /&gt;
| Oui&lt;br /&gt;
|-&lt;br /&gt;
| 443&lt;br /&gt;
| Accessible&lt;br /&gt;
| Oui&lt;br /&gt;
|-&lt;br /&gt;
| 2022&lt;br /&gt;
| Accessible&lt;br /&gt;
| Oui&lt;br /&gt;
|-&lt;br /&gt;
| 111&lt;br /&gt;
| Bloqué&lt;br /&gt;
| Oui&lt;br /&gt;
|-&lt;br /&gt;
| 2049&lt;br /&gt;
| Bloqué&lt;br /&gt;
| Oui&lt;br /&gt;
|-&lt;br /&gt;
| 9001&lt;br /&gt;
| Bloqué&lt;br /&gt;
| Oui&lt;br /&gt;
|-&lt;br /&gt;
| 9090&lt;br /&gt;
| Bloqué&lt;br /&gt;
| Oui&lt;br /&gt;
|-&lt;br /&gt;
| 4330&lt;br /&gt;
| Bloqué&lt;br /&gt;
| Oui&lt;br /&gt;
|-&lt;br /&gt;
| 44321–44323&lt;br /&gt;
| Bloqués&lt;br /&gt;
| Oui&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les résultats confirment le comportement attendu des règles IPv4 pour les ports TCP testés.&lt;br /&gt;
&lt;br /&gt;
=== 6.3 Tests internes ===&lt;br /&gt;
&lt;br /&gt;
Les vérifications précédentes ont confirmé :&lt;br /&gt;
&lt;br /&gt;
* les accès NFS depuis les serveurs du vRack ;&lt;br /&gt;
* le fonctionnement de Lighttpd ;&lt;br /&gt;
* le fonctionnement de la supervision Centreon ;&lt;br /&gt;
* les accès publics Apache et SFTPGo ;&lt;br /&gt;
* l&#039;accès SSH depuis le bureau.&lt;br /&gt;
&lt;br /&gt;
=== 6.4 Limites des tests ===&lt;br /&gt;
&lt;br /&gt;
Les tests extérieurs ont principalement porté sur IPv4 et TCP.&lt;br /&gt;
&lt;br /&gt;
Ils ne constituent pas un audit exhaustif de l&#039;exposition IPv6, des services UDP ou de la configuration applicative.&lt;br /&gt;
&lt;br /&gt;
Ces points doivent faire l&#039;objet de contrôles complémentaires.&lt;br /&gt;
&lt;br /&gt;
== 7. Fail2ban ==&lt;br /&gt;
&lt;br /&gt;
=== 7.1 Principe ===&lt;br /&gt;
&lt;br /&gt;
Fail2ban complète le pare-feu en bloquant temporairement certaines adresses IP à partir des événements détectés dans les journaux.&lt;br /&gt;
&lt;br /&gt;
Il ne remplace pas la politique de filtrage nftables.&lt;br /&gt;
&lt;br /&gt;
Les règles Fail2ban sont gérées indépendamment dans :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
table inet f2b-table&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 7.2 Vérification ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl status fail2ban&lt;br /&gt;
fail2ban-client status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vérification de la jail SSH :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
fail2ban-client status sshd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les autres jails doivent être contrôlées selon la configuration réellement active.&lt;br /&gt;
&lt;br /&gt;
Ne pas considérer qu&#039;une jail SFTPGo ou Cockpit existe sans l&#039;avoir vérifié.&lt;br /&gt;
&lt;br /&gt;
=== 7.3 Précautions ===&lt;br /&gt;
&lt;br /&gt;
* Ne pas supprimer la table Fail2ban.&lt;br /&gt;
* Ne pas utiliser &amp;lt;code&amp;gt;flush ruleset&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Vérifier les exclusions d&#039;adresses administratives.&lt;br /&gt;
* Contrôler régulièrement les bannissements.&lt;br /&gt;
* Vérifier les journaux en cas d&#039;activité inhabituelle.&lt;br /&gt;
&lt;br /&gt;
== 8. SSH ==&lt;br /&gt;
&lt;br /&gt;
=== 8.1 Politique réseau ===&lt;br /&gt;
&lt;br /&gt;
Le port SSH 22 est accessible depuis les adresses administratives autorisées.&lt;br /&gt;
&lt;br /&gt;
Il est bloqué depuis les autres adresses publiques IPv4.&lt;br /&gt;
&lt;br /&gt;
Le pare-feu ne prévoit pas d&#039;ouverture publique SSH en IPv6.&lt;br /&gt;
&lt;br /&gt;
=== 8.2 Authentification ===&lt;br /&gt;
&lt;br /&gt;
La configuration d&#039;authentification SSH doit être contrôlée séparément.&lt;br /&gt;
&lt;br /&gt;
Commandes :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sshd -T | grep -E \&lt;br /&gt;
  &#039;^(port|permitrootlogin|passwordauthentication|kbdinteractiveauthentication|pubkeyauthentication) &#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les restrictions par groupe doivent également être vérifiées dans les fichiers de configuration SSH.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; le filtrage réseau et l&#039;authentification SSH sont deux mécanismes distincts.&lt;br /&gt;
&lt;br /&gt;
== 9. SFTPGo ==&lt;br /&gt;
&lt;br /&gt;
SFTPGo est accessible publiquement sur le port TCP 2022.&lt;br /&gt;
&lt;br /&gt;
Son exposition est volontaire pour permettre les transferts clients.&lt;br /&gt;
&lt;br /&gt;
La sécurité repose notamment sur :&lt;br /&gt;
&lt;br /&gt;
* l&#039;authentification des utilisateurs ;&lt;br /&gt;
* les permissions des comptes ;&lt;br /&gt;
* la limitation des accès aux données ;&lt;br /&gt;
* la journalisation ;&lt;br /&gt;
* les éventuelles protections Fail2ban effectivement configurées.&lt;br /&gt;
&lt;br /&gt;
Vérification :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl status sftpgo&lt;br /&gt;
journalctl -u sftpgo --since &amp;quot;24 hours ago&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les interfaces d&#039;administration de SFTPGo ne doivent pas être exposées publiquement sans justification et protection adaptées.&lt;br /&gt;
&lt;br /&gt;
== 10. NFS et vRack ==&lt;br /&gt;
&lt;br /&gt;
Les échanges NFS sont autorisés sur le réseau privé :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
192.168.123.0/24&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les ports NFS et RPC ne sont pas accessibles depuis Internet lorsque le pare-feu AJLSM est actif.&lt;br /&gt;
&lt;br /&gt;
Vérifications :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
exportfs -v&lt;br /&gt;
showmount -e localhost&lt;br /&gt;
ss -tulpen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les exports NFS doivent conserver leurs propres restrictions d&#039;accès.&lt;br /&gt;
&lt;br /&gt;
Le pare-feu ne remplace pas les contrôles définis dans la configuration NFS.&lt;br /&gt;
&lt;br /&gt;
== 11. Supervision Centreon ==&lt;br /&gt;
&lt;br /&gt;
La supervision d&#039;EOLE3 doit utiliser son adresse privée vRack :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
192.168.123.202&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cette configuration permet de superviser les services internes sans ouvrir leurs ports sur Internet.&lt;br /&gt;
&lt;br /&gt;
Lors des tests du 16 octobre 2026, la supervision a été adaptée pour utiliser cette adresse.&lt;br /&gt;
&lt;br /&gt;
== 12. Tests réseau depuis l&#039;extérieur ==&lt;br /&gt;
&lt;br /&gt;
Pour tester réellement les restrictions Internet, il faut utiliser une connexion extérieure indépendante du bureau et des VPN.&lt;br /&gt;
&lt;br /&gt;
=== 12.1 Particularité du Mac AJLSM ===&lt;br /&gt;
&lt;br /&gt;
L&#039;adaptateur Ethernet USB du Mac utilise :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
en7&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le Wi-Fi utilise :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
en0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
macOS peut continuer à privilégier Ethernet même lorsque le partage de connexion de l&#039;iPhone est activé.&lt;br /&gt;
&lt;br /&gt;
=== 12.2 Procédure ===&lt;br /&gt;
&lt;br /&gt;
# Désactiver les VPN.&lt;br /&gt;
# Désactiver temporairement l&#039;adaptateur Ethernet &amp;lt;code&amp;gt;en7&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Connecter le Mac au partage de connexion de l&#039;iPhone.&lt;br /&gt;
# Vérifier la route et l&#039;adresse publique.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
route -n get 1.1.1.1&lt;br /&gt;
curl -4 https://api.ipify.org&lt;br /&gt;
echo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&#039;interface attendue est &amp;lt;code&amp;gt;en0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
L&#039;adresse publique doit être différente de celle du bureau.&lt;br /&gt;
&lt;br /&gt;
=== 12.3 Tester les ports ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for port in 22 80 443 2022 111 2049 9001 9090 4330 44321 44322 44323; do&lt;br /&gt;
    nc -vz -G 3 51.178.110.230 &amp;quot;$port&amp;quot; 2&amp;gt;&amp;amp;1&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Après les tests, réactiver Ethernet.&lt;br /&gt;
&lt;br /&gt;
== 13. Contrôles après redémarrage ==&lt;br /&gt;
&lt;br /&gt;
Après chaque redémarrage d&#039;EOLE3 :&lt;br /&gt;
&lt;br /&gt;
# vérifier le service AJLSM ;&lt;br /&gt;
# vérifier Fail2ban ;&lt;br /&gt;
# contrôler les tables nftables ;&lt;br /&gt;
# tester une nouvelle connexion SSH ;&lt;br /&gt;
# vérifier Apache et SFTPGo ;&lt;br /&gt;
# vérifier les échanges NFS ;&lt;br /&gt;
# contrôler Centreon.&lt;br /&gt;
&lt;br /&gt;
Commandes :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl is-active ajlsm-firewall.service&lt;br /&gt;
systemctl is-enabled ajlsm-firewall.service&lt;br /&gt;
&lt;br /&gt;
systemctl is-active fail2ban.service&lt;br /&gt;
&lt;br /&gt;
nft list tables&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 14. Règles à ne jamais oublier ==&lt;br /&gt;
&lt;br /&gt;
* Ne jamais utiliser &amp;lt;code&amp;gt;flush ruleset&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Ne jamais activer UFW en parallèle sans étude préalable.&lt;br /&gt;
* Ne jamais exposer NFS sur Internet.&lt;br /&gt;
* Ne jamais ouvrir Cockpit publiquement.&lt;br /&gt;
* Ne jamais modifier les adresses SSH autorisées sans accès de secours.&lt;br /&gt;
* Toujours conserver un mécanisme de retour arrière.&lt;br /&gt;
* Toujours tester depuis une véritable connexion extérieure.&lt;br /&gt;
* Toujours vérifier Fail2ban après une modification du pare-feu.&lt;br /&gt;
* Toujours vérifier les services internes après modification.&lt;br /&gt;
&lt;br /&gt;
== 15. Historique ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Date&lt;br /&gt;
! Intervention&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026&lt;br /&gt;
| Création et validation des règles nftables AJLSM&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026&lt;br /&gt;
| Validation des accès publics et des restrictions depuis le réseau mobile&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026&lt;br /&gt;
| Validation du démarrage, de l&#039;arrêt et du rechargement via systemd&lt;br /&gt;
|-&lt;br /&gt;
| 16/10/2026&lt;br /&gt;
| Activation du service au démarrage ; vérification finale de persistance à confirmer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Catégorie:Eole3]]&lt;br /&gt;
[[Catégorie:Sécurité]]&lt;br /&gt;
[[Catégorie:Infrastructure]]&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=EOLE3_%E2%80%94_Acc%C3%A8s_et_s%C3%A9curit%C3%A9&amp;diff=6483</id>
		<title>EOLE3 — Accès et sécurité</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=EOLE3_%E2%80%94_Acc%C3%A8s_et_s%C3%A9curit%C3%A9&amp;diff=6483"/>
		<updated>2026-10-16T12:33:02Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : Page blanchie&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=S%C3%A9curit%C3%A9_Eole3_%E2%80%93_R%C3%A8gles_%C3%A0_ne_pas_oublier&amp;diff=6482</id>
		<title>Sécurité Eole3 – Règles à ne pas oublier</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=S%C3%A9curit%C3%A9_Eole3_%E2%80%93_R%C3%A8gles_%C3%A0_ne_pas_oublier&amp;diff=6482"/>
		<updated>2026-10-16T12:31:34Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : Page blanchie&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.ajlsm.com/index.php?title=AJLSM-DEPLOY_%E2%80%94_D%C3%A9ploiement_automatis%C3%A9_des_VM_Proxmox&amp;diff=6481</id>
		<title>AJLSM-DEPLOY — Déploiement automatisé des VM Proxmox</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.ajlsm.com/index.php?title=AJLSM-DEPLOY_%E2%80%94_D%C3%A9ploiement_automatis%C3%A9_des_VM_Proxmox&amp;diff=6481"/>
		<updated>2026-10-15T22:01:53Z</updated>

		<summary type="html">&lt;p&gt;Jlarvers : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= AJLSM-DEPLOY — Déploiement automatisé des VM Proxmox =&lt;br /&gt;
&lt;br /&gt;
{{Note|Mise à jour du 15 octobre 2026. Les sections 1 à 13 conservent les informations de la recette initiale ; les ajouts et corrections actuels figurent en section 14. En cas de divergence, la procédure opérationnelle de la section 14 et le manuel installé sur Saturne3 prévalent.}}&lt;br /&gt;
&lt;br /&gt;
== 1. Présentation ==&lt;br /&gt;
&lt;br /&gt;
ajlsm-deploy est un outil Python permettant de déployer une nouvelle machine virtuelle Proxmox à partir de la VM modèle TEMPLATE3.&lt;br /&gt;
&lt;br /&gt;
L&#039;objectif est de standardiser les déploiements AJLSM tout en conservant un contrôle humain à chaque étape.&lt;br /&gt;
&lt;br /&gt;
Le script permet notamment :&lt;br /&gt;
&lt;br /&gt;
    Le clonage complet d&#039;une VM modèle.&lt;br /&gt;
    La configuration des ressources CPU, RAM et disque.&lt;br /&gt;
    Le premier démarrage avec les interfaces réseau isolées.&lt;br /&gt;
    La personnalisation du hostname et des identifiants système.&lt;br /&gt;
    La configuration réseau Netplan.&lt;br /&gt;
    La vérification de la disponibilité des adresses IPv4.&lt;br /&gt;
    L&#039;activation contrôlée du réseau.&lt;br /&gt;
    La configuration du démarrage automatique.&lt;br /&gt;
    La vérification des opérations effectuées. &lt;br /&gt;
&lt;br /&gt;
Chaque phase est indépendante.&lt;br /&gt;
&lt;br /&gt;
Aucune phase suivante n&#039;est exécutée automatiquement.&lt;br /&gt;
&lt;br /&gt;
L&#039;administrateur décide de poursuivre après examen des résultats.&lt;br /&gt;
== 2. Infrastructure de référence ==&lt;br /&gt;
=== 2.1. Serveur Proxmox ===&lt;br /&gt;
Élément 	Valeur&lt;br /&gt;
Hyperviseur 	Saturne3&lt;br /&gt;
Système 	Proxmox VE 9.2.1 lors de la recette&lt;br /&gt;
VM modèle 	TEMPLATE3&lt;br /&gt;
VMID modèle 	506&lt;br /&gt;
Stockage 	local-zfs&lt;br /&gt;
Script principal 	/usr/local/sbin/ajlsm-deploy&lt;br /&gt;
Répertoire des projets 	/etc/ajlsm/deploy/projets/&lt;br /&gt;
=== 2.2. Scripts ===&lt;br /&gt;
&lt;br /&gt;
Le script principal est installé dans :&lt;br /&gt;
&lt;br /&gt;
/usr/local/sbin/ajlsm-deploy&lt;br /&gt;
&lt;br /&gt;
Les scripts complémentaires utilisés lors du développement sont :&lt;br /&gt;
&lt;br /&gt;
ajlsm-deploy-check&lt;br /&gt;
ajlsm-deploy-resources&lt;br /&gt;
&lt;br /&gt;
Ils assurent respectivement les précontrôles et la configuration des ressources.&lt;br /&gt;
&lt;br /&gt;
Attention : vérifier leur emplacement et leur version lors de toute maintenance. La recette finale a confirmé l&#039;installation du script principal, mais ne constitue pas à elle seule un inventaire des versions de ses dépendances.&lt;br /&gt;
=== 2.3. Sauvegarde de la version précédente ===&lt;br /&gt;
&lt;br /&gt;
Avant l&#039;installation de la version actuelle, une sauvegarde a été créée :&lt;br /&gt;
&lt;br /&gt;
/usr/local/sbin/ajlsm-deploy.bak-20261015&lt;br /&gt;
&lt;br /&gt;
La nouvelle version a été installée avec :&lt;br /&gt;
&lt;br /&gt;
install -o root -g root -m 750 \&lt;br /&gt;
  /root/ajlsm-deploy-review/ajlsm-deploy-network-enable \&lt;br /&gt;
  /usr/local/sbin/ajlsm-deploy&lt;br /&gt;
&lt;br /&gt;
La syntaxe Python et l&#039;identité des deux fichiers ont été vérifiées :&lt;br /&gt;
&lt;br /&gt;
python3 -m py_compile /usr/local/sbin/ajlsm-deploy&lt;br /&gt;
 &lt;br /&gt;
cmp /usr/local/sbin/ajlsm-deploy \&lt;br /&gt;
    /root/ajlsm-deploy-review/ajlsm-deploy-network-enable&lt;br /&gt;
&lt;br /&gt;
== 3. Prérequis ==&lt;br /&gt;
=== 3.1. Sur l&#039;hyperviseur ===&lt;br /&gt;
&lt;br /&gt;
Les éléments suivants doivent être disponibles :&lt;br /&gt;
&lt;br /&gt;
    Python 3.&lt;br /&gt;
    PyYAML.&lt;br /&gt;
    Les outils Proxmox qm, pvesh et pvesm.&lt;br /&gt;
    La commande ip.&lt;br /&gt;
    Les scripts AJLSM nécessaires.&lt;br /&gt;
    Un stockage Proxmox opérationnel.&lt;br /&gt;
    Les bridges réseau définis dans le YAML. &lt;br /&gt;
&lt;br /&gt;
Les commandes sont exécutées avec les privilèges root sur le nœud Proxmox concerné.&lt;br /&gt;
=== 3.2. Dans TEMPLATE3 ===&lt;br /&gt;
&lt;br /&gt;
La VM modèle doit disposer :&lt;br /&gt;
&lt;br /&gt;
    D&#039;un système Linux compatible avec les scripts.&lt;br /&gt;
    De Python 3.&lt;br /&gt;
    De systemd.&lt;br /&gt;
    De l&#039;agent QEMU.&lt;br /&gt;
    De Netplan pour la configuration réseau.&lt;br /&gt;
    Du service ajlsm-clone-init.&lt;br /&gt;
    Des outils nécessaires à la personnalisation système. &lt;br /&gt;
&lt;br /&gt;
TEMPLATE3 doit être arrêtée avant le clonage.&lt;br /&gt;
=== 3.3. Vérification du modèle ===&lt;br /&gt;
&lt;br /&gt;
qm status 506&lt;br /&gt;
qm config 506&lt;br /&gt;
&lt;br /&gt;
Le résultat attendu est notamment :&lt;br /&gt;
&lt;br /&gt;
status: stopped&lt;br /&gt;
&lt;br /&gt;
L&#039;agent QEMU doit être activé dans la configuration Proxmox.&lt;br /&gt;
== 4. Configuration YAML ==&lt;br /&gt;
&lt;br /&gt;
Chaque projet possède son propre fichier YAML.&lt;br /&gt;
&lt;br /&gt;
Exemple :&lt;br /&gt;
&lt;br /&gt;
/etc/ajlsm/deploy/projets/mercure3.yaml&lt;br /&gt;
&lt;br /&gt;
=== 4.1. Exemple MERCURE3 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
projet:&lt;br /&gt;
  code: mercure3&lt;br /&gt;
  nom: MERCURE3&lt;br /&gt;
  environnement: interne&lt;br /&gt;
&lt;br /&gt;
proxmox:&lt;br /&gt;
  serveur: Saturne3&lt;br /&gt;
  template_vmid: 506&lt;br /&gt;
  vmid: null&lt;br /&gt;
  nom_vm: MERCURE3&lt;br /&gt;
&lt;br /&gt;
  cpu:&lt;br /&gt;
    sockets: 1&lt;br /&gt;
    cores: 8&lt;br /&gt;
&lt;br /&gt;
  memoire:&lt;br /&gt;
    maximale_mib: 24576&lt;br /&gt;
    minimale_mib: 16384&lt;br /&gt;
&lt;br /&gt;
  disque_systeme:&lt;br /&gt;
    stockage: local-zfs&lt;br /&gt;
    taille_gib: 100&lt;br /&gt;
    etendre_volume_racine: true&lt;br /&gt;
&lt;br /&gt;
  demarrage_auto: true&lt;br /&gt;
&lt;br /&gt;
  tags:&lt;br /&gt;
    - interne&lt;br /&gt;
&lt;br /&gt;
systeme:&lt;br /&gt;
  hostname: mercure3.ajlsm.com&lt;br /&gt;
&lt;br /&gt;
reseau:&lt;br /&gt;
  interfaces:&lt;br /&gt;
    - nom: net0&lt;br /&gt;
      bridge: vmbr2&lt;br /&gt;
      systeme: ens18&lt;br /&gt;
      ipv4: 10.0.0.43/24&lt;br /&gt;
&lt;br /&gt;
    - nom: net1&lt;br /&gt;
      bridge: vmbr1&lt;br /&gt;
      systeme: ens19&lt;br /&gt;
      ipv4: 192.168.123.27/24&lt;br /&gt;
&lt;br /&gt;
  loopback:&lt;br /&gt;
    ipv4: 51.83.117.113/32&lt;br /&gt;
&lt;br /&gt;
  passerelle:&lt;br /&gt;
    ipv4: 10.0.0.4&lt;br /&gt;
    interface: ens18&lt;br /&gt;
&lt;br /&gt;
  dns:&lt;br /&gt;
    - 10.0.0.4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 4.2. Attribution automatique du VMID ===&lt;br /&gt;
&lt;br /&gt;
Le paramètre :&lt;br /&gt;
&lt;br /&gt;
vmid: null&lt;br /&gt;
&lt;br /&gt;
indique que le VMID doit être déterminé automatiquement par Proxmox.&lt;br /&gt;
&lt;br /&gt;
Le script ne doit pas conserver un ancien VMID comme identifiant permanent du projet.&lt;br /&gt;
&lt;br /&gt;
Lors de la recette du 15 octobre 2026, Proxmox a réattribué le VMID 505 après suppression de l&#039;ancien clone.&lt;br /&gt;
&lt;br /&gt;
Le VMID proposé lors d&#039;une simulation n&#039;est pas réservé.&lt;br /&gt;
&lt;br /&gt;
Il peut donc changer avant le clonage effectif.&lt;br /&gt;
=== 4.3. Réutilisation pour un nouveau projet ===&lt;br /&gt;
&lt;br /&gt;
Pour déployer une autre VM :&lt;br /&gt;
&lt;br /&gt;
    Copier le fichier YAML d&#039;exemple.&lt;br /&gt;
    Modifier le code et le nom du projet.&lt;br /&gt;
    Modifier le hostname.&lt;br /&gt;
    Adapter CPU, RAM et disque.&lt;br /&gt;
    Définir les interfaces et les adresses IP.&lt;br /&gt;
    Vérifier les bridges Proxmox.&lt;br /&gt;
    Conserver vmid: null pour une attribution automatique.&lt;br /&gt;
    Exécuter les précontrôles. &lt;br /&gt;
&lt;br /&gt;
Le nom du fichier YAML n&#039;est pas imposé par le script.&lt;br /&gt;
== 5. Déploiement d&#039;une nouvelle VM (recette initiale) ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention :&#039;&#039;&#039; la procédure ci-dessous décrit les sept phases de la première recette. La procédure actualisée comprend l’extension racine et la postconfiguration ; voir section 14.2 avant tout nouveau déploiement.&lt;br /&gt;
&lt;br /&gt;
La procédure comporte sept phases :&lt;br /&gt;
&lt;br /&gt;
    Clonage.&lt;br /&gt;
    Configuration des ressources.&lt;br /&gt;
    Premier démarrage isolé.&lt;br /&gt;
    Personnalisation système.&lt;br /&gt;
    Préparation Netplan.&lt;br /&gt;
    Vérification de l&#039;activation réseau.&lt;br /&gt;
    Activation réseau. &lt;br /&gt;
&lt;br /&gt;
Chaque phase comporte une simulation lorsque l&#039;option correspondante est disponible.&lt;br /&gt;
=== 5.1. Phase 1 — Simulation du clonage ===&lt;br /&gt;
&lt;br /&gt;
ajlsm-deploy \&lt;br /&gt;
  /etc/ajlsm/deploy/projets/mercure3.yaml \&lt;br /&gt;
  --dry-run&lt;br /&gt;
&lt;br /&gt;
Cette commande vérifie :&lt;br /&gt;
&lt;br /&gt;
    La validité du YAML.&lt;br /&gt;
    La présence de TEMPLATE3.&lt;br /&gt;
    L&#039;arrêt de la VM modèle.&lt;br /&gt;
    La présence de l&#039;agent QEMU.&lt;br /&gt;
    Le stockage Proxmox.&lt;br /&gt;
    Les ressources demandées.&lt;br /&gt;
    Les bridges réseau.&lt;br /&gt;
    Les paramètres IP.&lt;br /&gt;
    La disponibilité d&#039;un VMID. &lt;br /&gt;
&lt;br /&gt;
Exemple de résultat :&lt;br /&gt;
&lt;br /&gt;
=== BILAN ===&lt;br /&gt;
Erreurs : 0&lt;br /&gt;
Avertissements : 1&lt;br /&gt;
Précontrôles satisfaits. Aucune modification effectuée.&lt;br /&gt;
 &lt;br /&gt;
=== PLAN DE CLONAGE ===&lt;br /&gt;
Source   : VM 506&lt;br /&gt;
Clone    : MERCURE3&lt;br /&gt;
VMID     : 505&lt;br /&gt;
Stockage : local-zfs&lt;br /&gt;
Type     : clone complet&lt;br /&gt;
Réseau   : isolation avant premier démarrage&lt;br /&gt;
Onboot   : désactivé&lt;br /&gt;
Démarrage: aucun&lt;br /&gt;
 &lt;br /&gt;
[DRY-RUN] Aucune modification effectuée.&lt;br /&gt;
&lt;br /&gt;
L&#039;avertissement concernant la disponibilité réelle des adresses IP est normal à ce stade : le contrôle réseau actif intervient ultérieurement.&lt;br /&gt;
=== 5.2. Phase 1 — Clonage effectif ===&lt;br /&gt;
&lt;br /&gt;
ajlsm-deploy \&lt;br /&gt;
  /etc/ajlsm/deploy/projets/mercure3.yaml \&lt;br /&gt;
  --clone&lt;br /&gt;
&lt;br /&gt;
Dans la version validée, le script demande :&lt;br /&gt;
&lt;br /&gt;
Pour créer la VM 505, saisir CLONER :&lt;br /&gt;
&lt;br /&gt;
La réponse attendue est :&lt;br /&gt;
&lt;br /&gt;
CLONER&lt;br /&gt;
&lt;br /&gt;
Le script effectue ensuite :&lt;br /&gt;
&lt;br /&gt;
    Le clonage complet.&lt;br /&gt;
    L&#039;isolation des interfaces.&lt;br /&gt;
    La vérification des adresses MAC.&lt;br /&gt;
    La vérification de l&#039;arrêt de la VM.&lt;br /&gt;
    La désactivation du démarrage automatique. &lt;br /&gt;
&lt;br /&gt;
Résultat attendu :&lt;br /&gt;
&lt;br /&gt;
=== CLONAGE TERMINÉ ===&lt;br /&gt;
VM 505 : MERCURE3&lt;br /&gt;
État : arrêtée, réseau isolé, onboot=0&lt;br /&gt;
Aucun démarrage effectué.&lt;br /&gt;
Prochaine phase : ressources CPU/RAM/disque.&lt;br /&gt;
&lt;br /&gt;
Ne pas démarrer manuellement la VM à ce stade.&lt;br /&gt;
=== 5.3. Phase 2 — Simulation des ressources ===&lt;br /&gt;
&lt;br /&gt;
ajlsm-deploy \&lt;br /&gt;
  /etc/ajlsm/deploy/projets/mercure3.yaml \&lt;br /&gt;
  --resources-dry-run&lt;br /&gt;
&lt;br /&gt;
Exemple :&lt;br /&gt;
&lt;br /&gt;
=== RESSOURCES : MERCURE3 (VM 505) ===&lt;br /&gt;
[OK] VM arrêtée, réseau isolé, onboot=0&lt;br /&gt;
[MODIFICATION] CPU : 2 x 4 -&amp;gt; 1 x 8&lt;br /&gt;
[MODIFICATION] RAM : 8192 -&amp;gt; 24576 Mio ; balloon : non défini -&amp;gt; 16384 Mio&lt;br /&gt;
[MODIFICATION] Disque scsi0 : 32 -&amp;gt; 100 Gio&lt;br /&gt;
 &lt;br /&gt;
[DRY-RUN] Aucune modification effectuée.&lt;br /&gt;
&lt;br /&gt;
=== 5.4. Phase 2 — Application des ressources ===&lt;br /&gt;
&lt;br /&gt;
ajlsm-deploy \&lt;br /&gt;
  /etc/ajlsm/deploy/projets/mercure3.yaml \&lt;br /&gt;
  --configure-resources&lt;br /&gt;
&lt;br /&gt;
Confirmation actuelle :&lt;br /&gt;
&lt;br /&gt;
Pour appliquer les ressources à la VM 505, saisir APPLIQUER :&lt;br /&gt;
&lt;br /&gt;
Répondre :&lt;br /&gt;
&lt;br /&gt;
APPLIQUER&lt;br /&gt;
&lt;br /&gt;
Résultat attendu :&lt;br /&gt;
&lt;br /&gt;
[OK] Ressources configurées et vérifiées.&lt;br /&gt;
[OK] VM toujours arrêtée et réseau isolé.&lt;br /&gt;
&lt;br /&gt;
Le disque virtuel est agrandi à la taille demandée.&lt;br /&gt;
&lt;br /&gt;
Important : l&#039;agrandissement du disque Proxmox et celui du système de fichiers invité sont deux opérations distinctes. Le YAML prévoit une extension du volume racine, mais la sortie de cette phase confirme uniquement la configuration des ressources Proxmox.&lt;br /&gt;
=== 5.5. Phase 3 — Simulation du premier démarrage ===&lt;br /&gt;
&lt;br /&gt;
ajlsm-deploy \&lt;br /&gt;
  /etc/ajlsm/deploy/projets/mercure3.yaml \&lt;br /&gt;
  --first-boot-dry-run&lt;br /&gt;
&lt;br /&gt;
Exemple :&lt;br /&gt;
&lt;br /&gt;
=== PREMIER DÉMARRAGE : MERCURE3 (VM 505) ===&lt;br /&gt;
[OK] Démarrage automatique désactivé, interfaces isolées&lt;br /&gt;
État actuel : stopped&lt;br /&gt;
[DRY-RUN] Démarrer la VM 505, réseau isolé&lt;br /&gt;
[DRY-RUN] Attendre la réponse de l&#039;agent QEMU (max. 300s)&lt;br /&gt;
[DRY-RUN] Vérifier ajlsm-clone-init et l&#039;UUID enregistré&lt;br /&gt;
&lt;br /&gt;
=== 5.6. Phase 3 — Premier démarrage réel ===&lt;br /&gt;
&lt;br /&gt;
ajlsm-deploy \&lt;br /&gt;
  /etc/ajlsm/deploy/projets/mercure3.yaml \&lt;br /&gt;
  --first-boot-apply&lt;br /&gt;
&lt;br /&gt;
Confirmation actuelle :&lt;br /&gt;
&lt;br /&gt;
Pour démarrer la VM 505 avec le réseau isolé, saisir DEMARRER :&lt;br /&gt;
&lt;br /&gt;
Répondre :&lt;br /&gt;
&lt;br /&gt;
DEMARRER&lt;br /&gt;
&lt;br /&gt;
Le script :&lt;br /&gt;
&lt;br /&gt;
    Démarre la VM avec ses interfaces isolées.&lt;br /&gt;
    Attend la disponibilité de l&#039;agent QEMU.&lt;br /&gt;
    Vérifie le service ajlsm-clone-init.&lt;br /&gt;
    Contrôle l&#039;UUID matériel du clone. &lt;br /&gt;
&lt;br /&gt;
Exemple :&lt;br /&gt;
&lt;br /&gt;
[OK] Agent QEMU disponible&lt;br /&gt;
[OK] ajlsm-clone-init terminé avec succès&lt;br /&gt;
[OK] UUID matériel conforme&lt;br /&gt;
[OK] Phase de premier démarrage validée ; interfaces toujours isolées&lt;br /&gt;
&lt;br /&gt;
==== Particularité : attente réseau au démarrage ====&lt;br /&gt;
&lt;br /&gt;
Lors de la recette, la console Proxmox a affiché :&lt;br /&gt;
&lt;br /&gt;
Job systemd-networkd-wait-online.service/start running&lt;br /&gt;
&lt;br /&gt;
Le démarrage s&#039;est poursuivi après environ 60 secondes.&lt;br /&gt;
&lt;br /&gt;
Cette attente est cohérente avec l&#039;isolation volontaire des interfaces réseau.&lt;br /&gt;
&lt;br /&gt;
Elle n&#039;a pas empêché l&#039;agent QEMU et ajlsm-clone-init de fonctionner.&lt;br /&gt;
&lt;br /&gt;
Une amélioration ultérieure de TEMPLATE3 pourra être étudiée pour éviter cette attente inutile pendant les phases isolées.&lt;br /&gt;
=== 5.7. Phase 4 — Simulation de personnalisation système ===&lt;br /&gt;
&lt;br /&gt;
ajlsm-deploy \&lt;br /&gt;
  /etc/ajlsm/deploy/projets/mercure3.yaml \&lt;br /&gt;
  --system-dry-run&lt;br /&gt;
&lt;br /&gt;
Cette phase prépare :&lt;br /&gt;
&lt;br /&gt;
    La sauvegarde des fichiers hostname et hosts.&lt;br /&gt;
    La sauvegarde des identifiants machine-id.&lt;br /&gt;
    La génération d&#039;une nouvelle identité système.&lt;br /&gt;
    Le redémarrage isolé.&lt;br /&gt;
    Les contrôles après redémarrage. &lt;br /&gt;
&lt;br /&gt;
Exemple :&lt;br /&gt;
&lt;br /&gt;
État de reprise : nouvelle transaction&lt;br /&gt;
 &lt;br /&gt;
[DRY-RUN] Sauvegarder hostname, hosts et les deux machine-id dans l&#039;invité&lt;br /&gt;
[DRY-RUN] Préparer une identité aléatoire persistante, puis redémarrer isolé&lt;br /&gt;
[DRY-RUN] Vérifier boot_id, identité PID1, hostname, hosts et isolation&lt;br /&gt;
&lt;br /&gt;
=== 5.8. Phase 4 — Personnalisation système ===&lt;br /&gt;
&lt;br /&gt;
ajlsm-deploy \&lt;br /&gt;
  /etc/ajlsm/deploy/projets/mercure3.yaml \&lt;br /&gt;
  --system-apply&lt;br /&gt;
&lt;br /&gt;
Confirmation :&lt;br /&gt;
&lt;br /&gt;
Cible : VM505 — mercure3.ajlsm.com&lt;br /&gt;
Cette opération modifiera l’identité système et redémarrera la VM avec le réseau isolé.&lt;br /&gt;
Confirmer (OUI/NON) :&lt;br /&gt;
&lt;br /&gt;
Répondre :&lt;br /&gt;
&lt;br /&gt;
oui&lt;br /&gt;
&lt;br /&gt;
Le script personnalise l&#039;identité système puis redémarre la VM.&lt;br /&gt;
&lt;br /&gt;
Résultat obtenu lors de la recette :&lt;br /&gt;
&lt;br /&gt;
[ACTION] Identité disque préparée ; identité active non encore validée&lt;br /&gt;
[OK] Agent QEMU disponible&lt;br /&gt;
[OK] ajlsm-clone-init terminé avec succès&lt;br /&gt;
[OK] Nouveau démarrage et identité active vérifiés ; VM505 toujours isolée&lt;br /&gt;
&lt;br /&gt;
==== Journal de personnalisation ====&lt;br /&gt;
&lt;br /&gt;
Les informations de transaction sont conservées dans l&#039;invité :&lt;br /&gt;
&lt;br /&gt;
/var/lib/ajlsm/system-personalisation/state.json&lt;br /&gt;
/var/lib/ajlsm/system-personalisation/backup/&lt;br /&gt;
&lt;br /&gt;
Ces éléments permettent au script de reconnaître une personnalisation déjà effectuée ou une transaction interrompue.&lt;br /&gt;
&lt;br /&gt;
Ne pas supprimer manuellement ces fichiers pour relancer une personnalisation.&lt;br /&gt;
&lt;br /&gt;
En cas d&#039;interruption, conserver la VM isolée et examiner les résultats des commandes dry-run avant toute reprise.&lt;br /&gt;
=== 5.9. Phase 5 — Simulation de la configuration réseau ===&lt;br /&gt;
&lt;br /&gt;
ajlsm-deploy \&lt;br /&gt;
  /etc/ajlsm/deploy/projets/mercure3.yaml \&lt;br /&gt;
  --network-dry-run&lt;br /&gt;
&lt;br /&gt;
Le script vérifie les paramètres réseau du YAML.&lt;br /&gt;
&lt;br /&gt;
Exemple :&lt;br /&gt;
&lt;br /&gt;
Cible : MERCURE3 VM505 ; reseau Proxmox isole&lt;br /&gt;
  ens18: 10.0.0.43/24&lt;br /&gt;
  ens19: 192.168.123.27/24&lt;br /&gt;
  lo: 51.83.117.113/32 ; passerelle: 10.0.0.4 (ens18) ; DNS: 10.0.0.4&lt;br /&gt;
 &lt;br /&gt;
[DRY-RUN] Sauvegarder le Netplan initial, ecrire la configuration et executer netplan generate&lt;br /&gt;
[DRY-RUN] Aucune modification ni activation reseau&lt;br /&gt;
&lt;br /&gt;
=== 5.10. Phase 5 — Application de Netplan ===&lt;br /&gt;
&lt;br /&gt;
ajlsm-deploy \&lt;br /&gt;
  /etc/ajlsm/deploy/projets/mercure3.yaml \&lt;br /&gt;
  --network-apply&lt;br /&gt;
&lt;br /&gt;
Confirmation :&lt;br /&gt;
&lt;br /&gt;
Cette operation remplace Netplan dans l&#039;invite, sans activer les interfaces Proxmox.&lt;br /&gt;
Confirmer (OUI/NON) :&lt;br /&gt;
&lt;br /&gt;
Répondre :&lt;br /&gt;
&lt;br /&gt;
oui&lt;br /&gt;
&lt;br /&gt;
Le script :&lt;br /&gt;
&lt;br /&gt;
    Sauvegarde la configuration Netplan initiale.&lt;br /&gt;
    Écrit la configuration du projet.&lt;br /&gt;
    Exécute netplan generate.&lt;br /&gt;
    Vérifie que les interfaces Proxmox restent isolées. &lt;br /&gt;
&lt;br /&gt;
Résultat obtenu :&lt;br /&gt;
&lt;br /&gt;
[OK] Netplan ecrit et netplan generate valide : {&amp;quot;changed&amp;quot;: true, &amp;quot;backup&amp;quot;: true}&lt;br /&gt;
[OK] VM505 toujours isolee ; aucune activation des liens&lt;br /&gt;
&lt;br /&gt;
Important : cette phase ne connecte pas les interfaces réseau.&lt;br /&gt;
=== 5.11. Phase 6 — Simulation de l&#039;activation réseau ===&lt;br /&gt;
&lt;br /&gt;
ajlsm-deploy \&lt;br /&gt;
  /etc/ajlsm/deploy/projets/mercure3.yaml \&lt;br /&gt;
  --network-enable-dry-run&lt;br /&gt;
&lt;br /&gt;
Cette commande effectue notamment :&lt;br /&gt;
&lt;br /&gt;
    La vérification de l&#039;agent QEMU.&lt;br /&gt;
    La vérification du service ajlsm-clone-init.&lt;br /&gt;
    La vérification de l&#039;identité de la VM.&lt;br /&gt;
    La validation de Netplan.&lt;br /&gt;
    Le contrôle ARP des adresses IPv4.&lt;br /&gt;
    La vérification de l&#039;isolation réseau. &lt;br /&gt;
&lt;br /&gt;
Exemple :&lt;br /&gt;
&lt;br /&gt;
[OK] ARP DAD 10.0.0.43 sur vmbr2 (aucune reponse)&lt;br /&gt;
[OK] ARP DAD 192.168.123.27 sur vmbr1 (aucune reponse)&lt;br /&gt;
[OK] VM505 UUID conforme, clone et Netplan valides, reseau isole&lt;br /&gt;
 &lt;br /&gt;
[DRY-RUN] Aucune modification. Activation puis controle et repli si erreur.&lt;br /&gt;
&lt;br /&gt;
==== Contrôle ARP DAD ====&lt;br /&gt;
&lt;br /&gt;
ARP DAD signifie Address Conflict Detection.&lt;br /&gt;
&lt;br /&gt;
Le script recherche une éventuelle réponse ARP indiquant qu&#039;une adresse IPv4 est déjà utilisée sur le réseau.&lt;br /&gt;
&lt;br /&gt;
L&#039;absence de réponse est nécessaire pour poursuivre, mais ne constitue pas une garantie absolue d&#039;absence de conflit.&lt;br /&gt;
&lt;br /&gt;
Il convient donc de vérifier également l&#039;attribution des adresses dans l&#039;inventaire réseau AJLSM.&lt;br /&gt;
=== 5.12. Phase 7 — Activation du réseau ===&lt;br /&gt;
&lt;br /&gt;
ajlsm-deploy \&lt;br /&gt;
  /etc/ajlsm/deploy/projets/mercure3.yaml \&lt;br /&gt;
  --network-enable&lt;br /&gt;
&lt;br /&gt;
Confirmation :&lt;br /&gt;
&lt;br /&gt;
Activer le reseau de cette VM (OUI/NON) :&lt;br /&gt;
&lt;br /&gt;
Répondre :&lt;br /&gt;
&lt;br /&gt;
oui&lt;br /&gt;
&lt;br /&gt;
Le script vérifie une nouvelle fois la disponibilité des adresses IPv4 avant l&#039;activation.&lt;br /&gt;
&lt;br /&gt;
Il contrôle ensuite :&lt;br /&gt;
&lt;br /&gt;
    Les adresses IPv4.&lt;br /&gt;
    L&#039;adresse loopback.&lt;br /&gt;
    La route par défaut.&lt;br /&gt;
    La configuration DNS.&lt;br /&gt;
    La réponse de la passerelle.&lt;br /&gt;
    Le démarrage automatique conformément au YAML. &lt;br /&gt;
&lt;br /&gt;
Résultat obtenu lors de la recette :&lt;br /&gt;
&lt;br /&gt;
[OK] ARP DAD 10.0.0.43 sur vmbr2 (aucune reponse)&lt;br /&gt;
[OK] ARP DAD 192.168.123.27 sur vmbr1 (aucune reponse)&lt;br /&gt;
[OK] Adresses, loopback, route, DNS et ping passerelle valides&lt;br /&gt;
[OK] VM505 : reseau actif et controle, onboot conforme au YAML&lt;br /&gt;
&lt;br /&gt;
Le script prévoit un mécanisme de repli en cas d&#039;échec de l&#039;activation réseau.&lt;br /&gt;
&lt;br /&gt;
Limite de la recette : le chemin nominal a été validé deux fois, mais le repli sur erreur n&#039;a pas encore été testé en situation réelle.&lt;br /&gt;
== 6. Vérifications finales ==&lt;br /&gt;
=== 6.1. État de la VM ===&lt;br /&gt;
&lt;br /&gt;
qm status 505&lt;br /&gt;
&lt;br /&gt;
Résultat attendu :&lt;br /&gt;
&lt;br /&gt;
status: running&lt;br /&gt;
&lt;br /&gt;
=== 6.2. Configuration Proxmox ===&lt;br /&gt;
&lt;br /&gt;
qm config 505&lt;br /&gt;
&lt;br /&gt;
Vérifier notamment :&lt;br /&gt;
&lt;br /&gt;
    Le nom MERCURE3.&lt;br /&gt;
    Les 8 vCPU.&lt;br /&gt;
    La mémoire de 24576 Mio.&lt;br /&gt;
    Le balloon de 16384 Mio.&lt;br /&gt;
    Le disque scsi0 de 100 Go.&lt;br /&gt;
    Les deux interfaces réseau actives.&lt;br /&gt;
    Le démarrage automatique. &lt;br /&gt;
&lt;br /&gt;
Contrôle ciblé :&lt;br /&gt;
&lt;br /&gt;
qm config 505 | grep -E &#039;^(name|net[0-9]+|onboot):&#039;&lt;br /&gt;
&lt;br /&gt;
Résultat attendu :&lt;br /&gt;
&lt;br /&gt;
name: MERCURE3&lt;br /&gt;
net0: ... link_down=0&lt;br /&gt;
net1: ... link_down=0&lt;br /&gt;
onboot: 1&lt;br /&gt;
&lt;br /&gt;
=== 6.3. Vérification du réseau dans l&#039;invité ===&lt;br /&gt;
&lt;br /&gt;
Lorsque nécessaire, utiliser la console Proxmox ou l&#039;agent QEMU.&lt;br /&gt;
&lt;br /&gt;
Exemples de commandes dans la VM :&lt;br /&gt;
&lt;br /&gt;
hostnamectl&lt;br /&gt;
 &lt;br /&gt;
ip -br addr&lt;br /&gt;
 &lt;br /&gt;
ip route&lt;br /&gt;
 &lt;br /&gt;
resolvectl status&lt;br /&gt;
 &lt;br /&gt;
systemctl status qemu-guest-agent --no-pager&lt;br /&gt;
&lt;br /&gt;
=== 6.4. Vérification du volume racine ===&lt;br /&gt;
&lt;br /&gt;
Le disque virtuel de 100 Go ne garantit pas, à lui seul, que le volume racine utilise tout cet espace.&lt;br /&gt;
&lt;br /&gt;
Vérifier dans l&#039;invité :&lt;br /&gt;
&lt;br /&gt;
lsblk&lt;br /&gt;
 &lt;br /&gt;
df -hT /&lt;br /&gt;
 &lt;br /&gt;
pvs&lt;br /&gt;
 &lt;br /&gt;
vgs&lt;br /&gt;
 &lt;br /&gt;
lvs&lt;br /&gt;
&lt;br /&gt;
Les trois dernières commandes concernent les installations utilisant LVM.&lt;br /&gt;
&lt;br /&gt;
Adapter les contrôles au partitionnement réel de TEMPLATE3.&lt;br /&gt;
== 7. Sécurité et principes de fonctionnement ==&lt;br /&gt;
=== 7.1. Isolation réseau ===&lt;br /&gt;
&lt;br /&gt;
La VM est clonée et démarrée avec ses interfaces réseau déconnectées au niveau Proxmox.&lt;br /&gt;
&lt;br /&gt;
Cette précaution évite notamment que le clone utilise temporairement les adresses réseau du modèle.&lt;br /&gt;
&lt;br /&gt;
Le réseau n&#039;est activé qu&#039;après :&lt;br /&gt;
&lt;br /&gt;
    L&#039;initialisation du clone.&lt;br /&gt;
    La personnalisation de son identité système.&lt;br /&gt;
    La préparation de Netplan.&lt;br /&gt;
    La vérification de la disponibilité des adresses IP. &lt;br /&gt;
&lt;br /&gt;
=== 7.2. Contrôle de l&#039;identité ===&lt;br /&gt;
&lt;br /&gt;
Le script utilise l&#039;identité de la VM Proxmox et son UUID matériel pour vérifier qu&#039;il agit sur la bonne cible.&lt;br /&gt;
&lt;br /&gt;
Cette protection est particulièrement importante lorsque le VMID est attribué automatiquement.&lt;br /&gt;
=== 7.3. Confirmations ===&lt;br /&gt;
&lt;br /&gt;
Les opérations modifiant la VM nécessitent une confirmation.&lt;br /&gt;
&lt;br /&gt;
Dans la version actuellement installée, les confirmations ne sont pas encore totalement uniformisées.&lt;br /&gt;
&lt;br /&gt;
Certaines phases demandent :&lt;br /&gt;
&lt;br /&gt;
CLONER&lt;br /&gt;
APPLIQUER&lt;br /&gt;
DEMARRER&lt;br /&gt;
&lt;br /&gt;
D&#039;autres utilisent :&lt;br /&gt;
&lt;br /&gt;
Confirmer (OUI/NON) :&lt;br /&gt;
&lt;br /&gt;
Il faut respecter la confirmation affichée par la version exécutée.&lt;br /&gt;
=== 7.4. Simulations ===&lt;br /&gt;
&lt;br /&gt;
Les commandes dry-run permettent d&#039;examiner la cible et les modifications prévues.&lt;br /&gt;
&lt;br /&gt;
Elles ne doivent pas être considérées comme une garantie absolue que l&#039;application réussira.&lt;br /&gt;
&lt;br /&gt;
L&#039;état de Proxmox, de la VM ou du réseau peut évoluer entre la simulation et l&#039;exécution.&lt;br /&gt;
=== 7.5. Reprise après incident ===&lt;br /&gt;
&lt;br /&gt;
En cas d&#039;erreur :&lt;br /&gt;
&lt;br /&gt;
    Ne pas poursuivre automatiquement avec la phase suivante.&lt;br /&gt;
    Examiner la sortie complète du script.&lt;br /&gt;
    Vérifier l&#039;état réel de la VM.&lt;br /&gt;
    Conserver les journaux et sauvegardes.&lt;br /&gt;
    Vérifier l&#039;isolation réseau avant toute reprise. &lt;br /&gt;
&lt;br /&gt;
Ne pas supprimer les fichiers de transaction de personnalisation pour forcer une nouvelle exécution.&lt;br /&gt;
== 8. Tableau récapitulatif des commandes (version de la recette initiale) ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;La liste complète actuelle est en section 14.2.&#039;&#039;&#039;&lt;br /&gt;
Phase 	Simulation 	Application&lt;br /&gt;
Clonage 	--dry-run 	--clone&lt;br /&gt;
Ressources 	--resources-dry-run 	--configure-resources&lt;br /&gt;
Premier démarrage 	--first-boot-dry-run 	--first-boot-apply&lt;br /&gt;
Système 	--system-dry-run 	--system-apply&lt;br /&gt;
Configuration réseau 	--network-dry-run 	--network-apply&lt;br /&gt;
Activation réseau 	--network-enable-dry-run 	--network-enable&lt;br /&gt;
&lt;br /&gt;
Toutes les commandes reçoivent le même fichier YAML.&lt;br /&gt;
&lt;br /&gt;
Exemple :&lt;br /&gt;
&lt;br /&gt;
ajlsm-deploy \&lt;br /&gt;
  /etc/ajlsm/deploy/projets/mercure3.yaml \&lt;br /&gt;
  --OPTION&lt;br /&gt;
&lt;br /&gt;
Remplacer OPTION par le mode souhaité.&lt;br /&gt;
== 9. Maintenance ==&lt;br /&gt;
=== 9.1. Vérification de la syntaxe ===&lt;br /&gt;
&lt;br /&gt;
python3 -m py_compile /usr/local/sbin/ajlsm-deploy&lt;br /&gt;
&lt;br /&gt;
=== 9.2. Affichage des options ===&lt;br /&gt;
&lt;br /&gt;
ajlsm-deploy --help&lt;br /&gt;
&lt;br /&gt;
=== 9.3. Sauvegarde avant modification ===&lt;br /&gt;
&lt;br /&gt;
Avant toute mise à jour :&lt;br /&gt;
&lt;br /&gt;
cp -a /usr/local/sbin/ajlsm-deploy \&lt;br /&gt;
  /usr/local/sbin/ajlsm-deploy.bak-$(date +%Y%m%d-%H%M%S)&lt;br /&gt;
&lt;br /&gt;
Si les scripts complémentaires sont modifiés, les sauvegarder également.&lt;br /&gt;
=== 9.4. Restauration de la version précédente ===&lt;br /&gt;
&lt;br /&gt;
La version sauvegardée le 15 octobre 2026 peut être restaurée avec :&lt;br /&gt;
&lt;br /&gt;
install -o root -g root -m 750 \&lt;br /&gt;
  /usr/local/sbin/ajlsm-deploy.bak-20261015 \&lt;br /&gt;
  /usr/local/sbin/ajlsm-deploy&lt;br /&gt;
&lt;br /&gt;
Attention : cette version ne possède pas nécessairement toutes les fonctions de la version actuelle.&lt;br /&gt;
&lt;br /&gt;
Vérifier la compatibilité avec les scripts complémentaires avant toute restauration.&lt;br /&gt;
== 10. Améliorations prévues (état historique à l’issue de la première recette) ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note 15/10/2026 :&#039;&#039;&#039; les paragraphes 10.1 à 10.4 ci-dessous sont conservés comme historique. Les confirmations OUI/NON, les suggestions de commandes, l’aide intégrée et le manuel système sont désormais présents. Voir section 14.&lt;br /&gt;
&lt;br /&gt;
Les améliorations suivantes ont été décidées à l&#039;issue de la recette.&lt;br /&gt;
&lt;br /&gt;
Elles ne sont pas encore intégrées dans la version installée.&lt;br /&gt;
=== 10.1. Uniformisation des confirmations ===&lt;br /&gt;
&lt;br /&gt;
Toutes les phases utiliseront :&lt;br /&gt;
&lt;br /&gt;
Confirmer (oui/non) :&lt;br /&gt;
&lt;br /&gt;
Comportement souhaité :&lt;br /&gt;
&lt;br /&gt;
    oui : exécuter.&lt;br /&gt;
    non : annuler.&lt;br /&gt;
    Réponse vide : annuler.&lt;br /&gt;
    Autre réponse : annuler. &lt;br /&gt;
&lt;br /&gt;
Les majuscules et minuscules devront être acceptées.&lt;br /&gt;
=== 10.2. Affichage des commandes suivantes ===&lt;br /&gt;
&lt;br /&gt;
Après chaque phase réussie, le script proposera les commandes permettant de poursuivre.&lt;br /&gt;
&lt;br /&gt;
Exemple :&lt;br /&gt;
&lt;br /&gt;
============================================================&lt;br /&gt;
[OK] RESSOURCES CONFIGURÉES&lt;br /&gt;
============================================================&lt;br /&gt;
 &lt;br /&gt;
VM : 505 (MERCURE3)&lt;br /&gt;
 &lt;br /&gt;
PROCHAINE ÉTAPE : PREMIER DÉMARRAGE&lt;br /&gt;
 &lt;br /&gt;
1. Simulation :&lt;br /&gt;
 &lt;br /&gt;
   ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml \&lt;br /&gt;
     --first-boot-dry-run&lt;br /&gt;
 &lt;br /&gt;
2. Application :&lt;br /&gt;
 &lt;br /&gt;
   ajlsm-deploy /etc/ajlsm/deploy/projets/mercure3.yaml \&lt;br /&gt;
     --first-boot-apply&lt;br /&gt;
 &lt;br /&gt;
============================================================&lt;br /&gt;
&lt;br /&gt;
Ces commandes seront uniquement affichées, jamais exécutées automatiquement.&lt;br /&gt;
=== 10.3. Aide intégrée ===&lt;br /&gt;
&lt;br /&gt;
Améliorer :&lt;br /&gt;
&lt;br /&gt;
ajlsm-deploy --help&lt;br /&gt;
&lt;br /&gt;
L&#039;aide devra être organisée par phases et rédigée en français.&lt;br /&gt;
=== 10.4. Manuel système ===&lt;br /&gt;
&lt;br /&gt;
Créer une page de manuel accessible avec :&lt;br /&gt;
&lt;br /&gt;
man ajlsm-deploy&lt;br /&gt;
&lt;br /&gt;
Elle devra présenter :&lt;br /&gt;
&lt;br /&gt;
    Les prérequis.&lt;br /&gt;
    La syntaxe des commandes.&lt;br /&gt;
    Le format YAML.&lt;br /&gt;
    Les différentes phases.&lt;br /&gt;
    Les contrôles de sécurité.&lt;br /&gt;
    Les procédures de reprise.&lt;br /&gt;
    Les exemples d&#039;utilisation. &lt;br /&gt;
&lt;br /&gt;
=== 10.5. Optimisation de TEMPLATE3 ===&lt;br /&gt;
&lt;br /&gt;
Étudier l&#039;attente de 60 secondes observée lors du premier démarrage isolé.&lt;br /&gt;
&lt;br /&gt;
Vérifier si systemd-networkd-wait-online est nécessaire et, le cas échéant, adapter son comportement sans perturber les dépendances réseau.&lt;br /&gt;
== 11. Fichiers de développement et nettoyage ==&lt;br /&gt;
&lt;br /&gt;
Le répertoire utilisé pour la recette est :&lt;br /&gt;
&lt;br /&gt;
/root/ajlsm-deploy-review/&lt;br /&gt;
&lt;br /&gt;
Il contient notamment :&lt;br /&gt;
&lt;br /&gt;
ajlsm-deploy&lt;br /&gt;
ajlsm-deploy-check&lt;br /&gt;
ajlsm-deploy-resources&lt;br /&gt;
ajlsm-deploy-network-enable&lt;br /&gt;
INSTRUCTIONS-TEST.txt&lt;br /&gt;
&lt;br /&gt;
Le fichier INSTRUCTIONS-TEST.txt correspond à une ancienne phase de développement.&lt;br /&gt;
&lt;br /&gt;
Il ne décrit pas l&#039;ensemble des fonctionnalités réseau désormais disponibles.&lt;br /&gt;
&lt;br /&gt;
Il doit donc être considéré comme obsolète.&lt;br /&gt;
&lt;br /&gt;
Après vérification et archivage éventuel, il pourra être supprimé :&lt;br /&gt;
&lt;br /&gt;
rm /root/ajlsm-deploy-review/INSTRUCTIONS-TEST.txt&lt;br /&gt;
&lt;br /&gt;
Ne pas supprimer les autres fichiers de développement tant que leur rôle et leur emplacement définitif n&#039;ont pas été vérifiés.&lt;br /&gt;
== 12. Historique des validations ==&lt;br /&gt;
Date 	Opération 	Résultat&lt;br /&gt;
15/10/2026 	Installation du script avec activation réseau 	Validée&lt;br /&gt;
15/10/2026 	Premier déploiement MERCURE3 	Validé&lt;br /&gt;
15/10/2026 	Suppression du premier clone 	Effectuée&lt;br /&gt;
15/10/2026 	Second clonage complet depuis TEMPLATE3 	Validé&lt;br /&gt;
15/10/2026 	Configuration CPU/RAM/disque 	Validée&lt;br /&gt;
15/10/2026 	Premier démarrage isolé 	Validé&lt;br /&gt;
15/10/2026 	Personnalisation système 	Validée&lt;br /&gt;
15/10/2026 	Configuration Netplan 	Validée&lt;br /&gt;
15/10/2026 	Contrôle ARP des adresses IPv4 	Validé&lt;br /&gt;
15/10/2026 	Activation réseau et contrôles 	Validée&lt;br /&gt;
À réaliser 	Test du repli automatique sur échec réseau 	Non testé&lt;br /&gt;
À réaliser 	Harmonisation des confirmations et aide intégrée 	Non réalisée&lt;br /&gt;
== 13. Conclusion ==&lt;br /&gt;
&lt;br /&gt;
La procédure de déploiement AJLSM a été validée par deux déploiements successifs de MERCURE3.&lt;br /&gt;
&lt;br /&gt;
Le second déploiement a été effectué depuis une VM modèle arrêtée, après suppression du premier clone.&lt;br /&gt;
&lt;br /&gt;
Toutes les phases ont été exécutées successivement avec leurs contrôles.&lt;br /&gt;
&lt;br /&gt;
Le réseau a été activé uniquement après personnalisation du système et vérification de sa configuration.&lt;br /&gt;
&lt;br /&gt;
Le fonctionnement nominal de la chaîne de déploiement est validé.&lt;br /&gt;
&lt;br /&gt;
Les principaux travaux restants concernent l&#039;ergonomie, la documentation intégrée, la vérification de l&#039;extension du volume racine et les essais du mécanisme de repli réseau.&lt;br /&gt;
Catégories :&lt;br /&gt;
&lt;br /&gt;
    InfrastructureProxmoxDéploiementAJLSMAJLSM-DEPLOY — Déploiement automatisé des VM Proxmox&lt;br /&gt;
&lt;br /&gt;
== 14. Actualisation technique du 15 octobre 2026 ==&lt;br /&gt;
&lt;br /&gt;
=== 14.1. Périmètre et emplacement des fichiers ===&lt;br /&gt;
&lt;br /&gt;
Cette section complète les treize sections historiques précédentes. Elle reflète les fonctions documentées dans l&#039;aide de la version courante et les corrections testées le 15 octobre 2026. Elle ne constitue pas une validation d&#039;une nouvelle recette complète.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Élément !! Emplacement / valeur&lt;br /&gt;
|-&lt;br /&gt;
| Hyperviseur || Saturne3 (Proxmox VE)&lt;br /&gt;
|-&lt;br /&gt;
| Modèle || TEMPLATE3, VMID 506&lt;br /&gt;
|-&lt;br /&gt;
| VM de recette || MERCURE3, VMID 505 (ne pas supposer que 505 sera réattribué)&lt;br /&gt;
|-&lt;br /&gt;
| Programme principal || &amp;lt;code&amp;gt;/usr/local/sbin/ajlsm-deploy&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Extension racine || &amp;lt;code&amp;gt;/usr/local/sbin/ajlsm_deploy_rootgrow.py&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Postconfiguration || &amp;lt;code&amp;gt;/usr/local/sbin/ajlsm_deploy_postconfig.py&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Configurations || &amp;lt;code&amp;gt;/etc/ajlsm/deploy/projets/&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| README d&#039;exploitation || &amp;lt;code&amp;gt;/usr/local/sbin/README-ajlsm-deploy&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Manuel système || &amp;lt;code&amp;gt;/usr/local/man/man8/ajlsm-deploy.8&amp;lt;/code&amp;gt; ; &amp;lt;code&amp;gt;man 8 ajlsm-deploy&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Dossier de revue || &amp;lt;code&amp;gt;/root/ajlsm-deploy-review/&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Sauvegardes des correctifs || &amp;lt;code&amp;gt;/root/ajlsm-deploy-review/correctifs-20261015/&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les programmes autonomes &amp;lt;code&amp;gt;ajlsm-deploy-check&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;ajlsm-deploy-resources&amp;lt;/code&amp;gt; figurent également dans le manuel. Leur présence et leur version effectives sont à vérifier avant toute intervention.&lt;br /&gt;
&lt;br /&gt;
Le README situé dans &amp;lt;code&amp;gt;/home/ajlsm/README&amp;lt;/code&amp;gt; sur TEMPLATE3 et hérité par MERCURE3 est le README &#039;&#039;applicatif&#039;&#039; Pleade/Drupal. Il ne doit pas être remplacé par le README de l&#039;outil de déploiement.&lt;br /&gt;
&lt;br /&gt;
La VM 515 n&#039;appartient pas à cette recette et ne doit pas être modifiée.&lt;br /&gt;
&lt;br /&gt;
=== 14.2. Ordre actuel des phases ===&lt;br /&gt;
&lt;br /&gt;
Toutes les commandes suivantes sont à exécuter &#039;&#039;une par une&#039;&#039;, sur Saturne3, avec les droits &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;. Aucune commande suggérée par l&#039;outil n&#039;est exécutée automatiquement. Ne jamais enchaîner les phases sans examiner les résultats.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
PROJET=/etc/ajlsm/deploy/projets/mercure3.yaml&lt;br /&gt;
&lt;br /&gt;
# 1. Clonage&lt;br /&gt;
ajlsm-deploy &amp;quot;$PROJET&amp;quot; --dry-run&lt;br /&gt;
ajlsm-deploy &amp;quot;$PROJET&amp;quot; --clone&lt;br /&gt;
&lt;br /&gt;
# 2. Ressources Proxmox&lt;br /&gt;
ajlsm-deploy &amp;quot;$PROJET&amp;quot; --resources-dry-run&lt;br /&gt;
ajlsm-deploy &amp;quot;$PROJET&amp;quot; --configure-resources&lt;br /&gt;
&lt;br /&gt;
# 3. Premier démarrage isolé&lt;br /&gt;
ajlsm-deploy &amp;quot;$PROJET&amp;quot; --first-boot-dry-run&lt;br /&gt;
ajlsm-deploy &amp;quot;$PROJET&amp;quot; --first-boot-apply&lt;br /&gt;
&lt;br /&gt;
# 4. Extension du volume racine&lt;br /&gt;
ajlsm-deploy &amp;quot;$PROJET&amp;quot; --root-grow-dry-run&lt;br /&gt;
ajlsm-deploy &amp;quot;$PROJET&amp;quot; --root-grow-apply&lt;br /&gt;
&lt;br /&gt;
# 5. Identité système&lt;br /&gt;
ajlsm-deploy &amp;quot;$PROJET&amp;quot; --system-dry-run&lt;br /&gt;
ajlsm-deploy &amp;quot;$PROJET&amp;quot; --system-apply&lt;br /&gt;
&lt;br /&gt;
# 6. Préparation Netplan (réseau encore isolé)&lt;br /&gt;
ajlsm-deploy &amp;quot;$PROJET&amp;quot; --network-dry-run&lt;br /&gt;
ajlsm-deploy &amp;quot;$PROJET&amp;quot; --network-apply&lt;br /&gt;
&lt;br /&gt;
# 7. Activation réseau&lt;br /&gt;
ajlsm-deploy &amp;quot;$PROJET&amp;quot; --network-enable-dry-run&lt;br /&gt;
ajlsm-deploy &amp;quot;$PROJET&amp;quot; --network-enable&lt;br /&gt;
&lt;br /&gt;
# 8. Audit SSH et synchronisation de l&#039;identité SSH&lt;br /&gt;
ajlsm-deploy &amp;quot;$PROJET&amp;quot; --ssh-audit&lt;br /&gt;
&lt;br /&gt;
# 9. Durcissement SSH et contrôle&lt;br /&gt;
ajlsm-deploy &amp;quot;$PROJET&amp;quot; --ssh-secure&lt;br /&gt;
ajlsm-deploy &amp;quot;$PROJET&amp;quot; --ssh-audit&lt;br /&gt;
&lt;br /&gt;
# 10. Mot de passe du compte ajlsm&lt;br /&gt;
ajlsm-deploy &amp;quot;$PROJET&amp;quot; --password-ajlsm&lt;br /&gt;
&lt;br /&gt;
# 11. Certificat TLS interne&lt;br /&gt;
ajlsm-deploy &amp;quot;$PROJET&amp;quot; --tls-apply&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le choix de la phase est exclusif. Les simulations proposent l&#039;application correspondante ; les succès proposent la simulation suivante. Le script n&#039;exécute jamais la suggestion.&lt;br /&gt;
&lt;br /&gt;
=== 14.3. Extension de la partition, de LVM et d&#039;ext4 ===&lt;br /&gt;
&lt;br /&gt;
La phase &amp;lt;code&amp;gt;--configure-resources&amp;lt;/code&amp;gt; agrandit le disque virtuel Proxmox, mais n&#039;agrandit pas à elle seule le volume racine du système invité. L&#039;extension intervient &#039;&#039;après le premier démarrage isolé&#039;&#039; et &#039;&#039;avant la personnalisation système&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;--root-grow-dry-run&amp;lt;/code&amp;gt; : vérification sans écriture de la topologie, du disque, de la partition terminale, du volume physique, du volume logique et du système de fichiers.&lt;br /&gt;
* &amp;lt;code&amp;gt;--root-grow-apply&amp;lt;/code&amp;gt; : après confirmation, exécution de &amp;lt;code&amp;gt;growpart /dev/sda 3&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;pvresize /dev/sda3&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;lvextend -r -l +100%FREE&amp;lt;/code&amp;gt; sur le LV racine.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Limitation de sécurité :&#039;&#039;&#039; la procédure est limitée à la topologie contrôlée de TEMPLATE3 : &amp;lt;code&amp;gt;/dev/sda3&amp;lt;/code&amp;gt;, un unique PV, un unique LV racine et ext4. Une autre topologie doit être refusée. Aucun paquet ne doit être installé pendant cette phase.&lt;br /&gt;
&lt;br /&gt;
Contrôles manuels possibles dans l&#039;invité :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
lsblk&lt;br /&gt;
df -hT /&lt;br /&gt;
pvs&lt;br /&gt;
vgs&lt;br /&gt;
lvs&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le 15 octobre 2026, la compilation du module a été validée. L&#039;extension doit encore être confirmée au cours d&#039;une recette intégrale avec la version actuelle.&lt;br /&gt;
&lt;br /&gt;
=== 14.4. Identité système et préparation du réseau ===&lt;br /&gt;
&lt;br /&gt;
Les phases &amp;lt;code&amp;gt;--system-dry-run&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;--system-apply&amp;lt;/code&amp;gt; personnalisent le hostname, &amp;lt;code&amp;gt;/etc/hosts&amp;lt;/code&amp;gt; et le &amp;lt;code&amp;gt;machine-id&amp;lt;/code&amp;gt;, en respectant le journal de reprise. La VM reste isolée. Le journal de transaction de l&#039;invité est conservé sous &amp;lt;code&amp;gt;/var/lib/ajlsm/system-personalisation/&amp;lt;/code&amp;gt; ; ne pas le supprimer pour forcer une reprise.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;--network-dry-run&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;--network-apply&amp;lt;/code&amp;gt; préparent Netplan et vérifient &amp;lt;code&amp;gt;netplan generate&amp;lt;/code&amp;gt; sans activer les interfaces Proxmox.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;--network-enable-dry-run&amp;lt;/code&amp;gt; vérifie l&#039;identité et la configuration, puis recherche des réponses ARP sur les adresses des interfaces. Cette simulation émet des paquets ARP : elle ne modifie pas la configuration, mais n&#039;est pas passive sur le réseau. L&#039;absence de réponse ARP ne prouve pas qu&#039;une adresse est libre.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;--network-enable&amp;lt;/code&amp;gt; active les liens, contrôle adresses, loopback, route, DNS et passerelle, puis applique le paramètre de démarrage automatique du YAML. Le mécanisme de repli vers l&#039;isolation en cas d&#039;échec doit encore faire l&#039;objet d&#039;un essai réel sur une VM dédiée.&lt;br /&gt;
&lt;br /&gt;
=== 14.5. Audit SSH et vérification indépendante de la clé ED25519 ===&lt;br /&gt;
&lt;br /&gt;
L&#039;audit &amp;lt;code&amp;gt;--ssh-audit&amp;lt;/code&amp;gt; a été complété par une synchronisation de l&#039;identité SSH de la VM &#039;&#039;avant&#039;&#039; les vérifications d&#039;accès.&lt;br /&gt;
&lt;br /&gt;
# Le programme résout le VMID cible à partir du projet et de Proxmox.&lt;br /&gt;
# Il lit la clé publique d&#039;hôte &amp;lt;code&amp;gt;/etc/ssh/ssh_host_ed25519_key.pub&amp;lt;/code&amp;gt; &#039;&#039;dans l&#039;invité&#039;&#039; via l&#039;agent QEMU.&lt;br /&gt;
# Il vérifie le format de la clé ED25519, notamment sa structure binaire attendue.&lt;br /&gt;
# Il interroge &#039;&#039;indépendamment&#039;&#039; le service SSH exposé sur le réseau à l&#039;aide de &amp;lt;code&amp;gt;ssh-keyscan -T 8 -t ed25519&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Il compare les deux clés. Une clé absente, malformée ou différente entraîne un refus sans remplacement de &amp;lt;code&amp;gt;known_hosts&amp;lt;/code&amp;gt;.&lt;br /&gt;
# En cas de concordance, il sauvegarde &amp;lt;code&amp;gt;/root/.ssh/known_hosts&amp;lt;/code&amp;gt; sur Saturne3, retire les anciennes entrées de l&#039;adresse IP sur une copie de travail, y compris les entrées hachées, puis écrit la nouvelle entrée vérifiée par remplacement atomique. Les autres hôtes restent inchangés.&lt;br /&gt;
# Il lance ensuite l&#039;audit des accès SSH, des clés autorisées, de sudo et du compte &amp;lt;code&amp;gt;ajlsm&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Précision :&#039;&#039;&#039; l&#039;audit des paramètres SSH &#039;&#039;dans la VM&#039;&#039; est en lecture seule ; cependant, la synchronisation préalable peut modifier &amp;lt;code&amp;gt;/root/.ssh/known_hosts&amp;lt;/code&amp;gt; &#039;&#039;sur Saturne3&#039;&#039;. La description historique « sans modification » ne s&#039;applique donc pas au fichier d&#039;hôtes SSH de l&#039;hyperviseur.&lt;br /&gt;
&lt;br /&gt;
Les tests isolés du 15 octobre 2026 ont confirmé :&lt;br /&gt;
* Clés concordantes : acceptation et écriture.&lt;br /&gt;
* Clés divergentes : refus sans modification.&lt;br /&gt;
* Clé malformée : refus sans modification.&lt;br /&gt;
* Préservation des autres entrées, y compris lors du traitement des anciennes entrées hachées.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Limite de validation :&#039;&#039;&#039; ces essais étaient fonctionnels et isolés ; ils n&#039;ont pas constitué une connexion complète à une nouvelle VM MERCURE3. La recette de bout en bout reste à effectuer.&lt;br /&gt;
&lt;br /&gt;
=== 14.6. Durcissement SSH, compte ajlsm et TLS ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;--ssh-secure&amp;lt;/code&amp;gt; désactive l&#039;authentification SSH par mot de passe et conserve l&#039;accès root par clé publique. Avant application, vérifier les accès par clé ; après application, relancer &amp;lt;code&amp;gt;--ssh-audit&amp;lt;/code&amp;gt;. Ne pas fermer la dernière session administrative fonctionnelle avant vérification.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;--password-ajlsm&amp;lt;/code&amp;gt; lance une saisie interactive masquée, répétée deux fois, pour définir le mot de passe du compte &amp;lt;code&amp;gt;ajlsm&amp;lt;/code&amp;gt;. Le mot de passe ne doit pas être inscrit dans le YAML ou dans la ligne de commande. Le conserver dans le registre d&#039;administration prévu (ODS), conformément à la procédure AJLSM.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;--tls-apply&amp;lt;/code&amp;gt; vérifie le certificat TLS interne. Si un certificat personnalisé est déjà en place, il ne doit pas être écrasé inutilement ; sinon l&#039;initialisation s&#039;effectue après confirmation, suivie des contrôles Apache.&lt;br /&gt;
&lt;br /&gt;
Ces fonctions appartiennent à la postconfiguration de la VM. Elles ne remplacent pas les travaux applicatifs ultérieurs sur les montages NFS, les VirtualHosts Apache, Drupal et Pleade.&lt;br /&gt;
&lt;br /&gt;
=== 14.7. Format YAML et protections ===&lt;br /&gt;
&lt;br /&gt;
Le fichier YAML reste la source de configuration. Les sections obligatoires sont &amp;lt;code&amp;gt;projet&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;proxmox&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;systeme&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;reseau&amp;lt;/code&amp;gt;. Les clés inconnues, répétées ou manquantes sont refusées par les contrôles prévus ; les types sont vérifiés. Seul &amp;lt;code&amp;gt;proxmox.vmid&amp;lt;/code&amp;gt; peut être &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; pour l&#039;attribution automatique.&lt;br /&gt;
&lt;br /&gt;
L&#039;attribution d&#039;un VMID lors d&#039;une simulation ne constitue pas une réservation. Vérifier l&#039;identité de la VM et son VMID à chaque opération. La VM modèle 506 doit être arrêtée avant clonage ; ne jamais agir sur la VM 515.&lt;br /&gt;
&lt;br /&gt;
Les adresses IPv4 des interfaces sont indiquées avec préfixe CIDR, la loopback en &amp;lt;code&amp;gt;/32&amp;lt;/code&amp;gt;, les DNS sous forme d&#039;une liste non vide d&#039;IPv4. La passerelle doit appartenir au sous-réseau de l&#039;interface déclarée. Les paramètres de réseau sont contrôlés avant activation, mais les contrôles ARP ne remplacent pas l&#039;inventaire d&#039;adressage.&lt;br /&gt;
&lt;br /&gt;
=== 14.8. Confirmations, codes de sortie et reprise ===&lt;br /&gt;
&lt;br /&gt;
Les confirmations de la version actuelle acceptent uniquement &amp;lt;code&amp;gt;OUI&amp;lt;/code&amp;gt; (sans distinction de casse, espaces périphériques ignorés). &amp;lt;code&amp;gt;NON&amp;lt;/code&amp;gt;, une réponse vide, toute autre réponse ou une interruption annulent. La valeur par défaut est donc le refus. Une phase déjà conforme peut se terminer sans confirmation si elle n&#039;a rien à modifier.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Code !! Signification&lt;br /&gt;
|-&lt;br /&gt;
| 0 || Succès&lt;br /&gt;
|-&lt;br /&gt;
| 1 || Annulation&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Erreur de configuration, de contrôle ou d&#039;exécution&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
En cas d&#039;échec, ne pas poursuivre : conserver la sortie complète, identifier le VMID, vérifier l&#039;état réel de la VM et son isolation réseau, examiner les journaux et les sauvegardes. Ne jamais contourner une divergence de clés SSH en supprimant aveuglément &amp;lt;code&amp;gt;known_hosts&amp;lt;/code&amp;gt;. Ne jamais effacer le journal de transaction système pour relancer artificiellement une phase.&lt;br /&gt;
&lt;br /&gt;
=== 14.9. Maintenance et documentation installée ===&lt;br /&gt;
&lt;br /&gt;
Sur Saturne3 :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Vérifier les trois scripts Python&lt;br /&gt;
python3 -m py_compile \&lt;br /&gt;
  /usr/local/sbin/ajlsm-deploy \&lt;br /&gt;
  /usr/local/sbin/ajlsm_deploy_rootgrow.py \&lt;br /&gt;
  /usr/local/sbin/ajlsm_deploy_postconfig.py&lt;br /&gt;
&lt;br /&gt;
# Aide et documentation&lt;br /&gt;
ajlsm-deploy --help&lt;br /&gt;
man 8 ajlsm-deploy&lt;br /&gt;
cat /usr/local/sbin/README-ajlsm-deploy&lt;br /&gt;
&lt;br /&gt;
# Identifier le manuel installé&lt;br /&gt;
man -w ajlsm-deploy&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Le manuel se trouve dans &amp;lt;code&amp;gt;/usr/local/man/man8/ajlsm-deploy.8&amp;lt;/code&amp;gt;, en section 8 (administration système). Il a été actualisé le 15 octobre 2026 : ordre des exemples, synchronisation ED25519 et limites de validation. Une sauvegarde du manuel précédent a été déplacée hors du répertoire &amp;lt;code&amp;gt;man8&amp;lt;/code&amp;gt;, dans &amp;lt;code&amp;gt;/root/ajlsm-deploy-review/sauvegardes-man/&amp;lt;/code&amp;gt;, pour éviter l&#039;avertissement « ignoring bogus filename ».&lt;br /&gt;
&lt;br /&gt;
Les trois scripts Python doivent être sauvegardés ensemble avant correction ou restauration ; leur compatibilité doit être vérifiée. Les sauvegardes des correctifs du 15 octobre sont conservées dans &amp;lt;code&amp;gt;/root/ajlsm-deploy-review/correctifs-20261015/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== 14.10. Historique complémentaire des validations ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Date !! Opération !! Statut&lt;br /&gt;
|-&lt;br /&gt;
| 15/10/2026 || Recette historique : clonage, ressources, premier démarrage, identité, Netplan, contrôle ARP et activation réseau || Validé lors de la recette initiale MERCURE3&lt;br /&gt;
|-&lt;br /&gt;
| 15/10/2026 || Compilation Python du programme principal et des deux modules &amp;lt;code&amp;gt;rootgrow&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;postconfig&amp;lt;/code&amp;gt; || Validée&lt;br /&gt;
|-&lt;br /&gt;
| 15/10/2026 || Comparaison ED25519 : concordance, divergence et clé malformée || Validée en tests isolés&lt;br /&gt;
|-&lt;br /&gt;
| 15/10/2026 || Protection et mise à jour de &amp;lt;code&amp;gt;known_hosts&amp;lt;/code&amp;gt; || Validée en tests isolés&lt;br /&gt;
|-&lt;br /&gt;
| 15/10/2026 || README d&#039;exploitation sur Saturne3 || Rédigé ; présence effective à vérifier si nécessaire&lt;br /&gt;
|-&lt;br /&gt;
| 15/10/2026 || Manuel système section 8, mise à jour SSH et ordre des exemples || Actualisé et affichage vérifié&lt;br /&gt;
|-&lt;br /&gt;
| À réaliser || Extension racine avec le jeu actuel de scripts || Recette complète non confirmée&lt;br /&gt;
|-&lt;br /&gt;
| À réaliser || Chaîne complète jusqu&#039;à SSH, mot de passe et TLS sur un nouveau clone || Recette complète non confirmée&lt;br /&gt;
|-&lt;br /&gt;
| À réaliser || Test d&#039;échec réseau et du mécanisme de repli || Non testé&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 14.11. Travaux restant hors du périmètre système ===&lt;br /&gt;
&lt;br /&gt;
Une fois la recette du socle système terminée, les prochaines étapes d&#039;automatisation concernent :&lt;br /&gt;
&lt;br /&gt;
# Les montages NFS et leurs dépendances.&lt;br /&gt;
# La personnalisation des VirtualHosts et des services Apache.&lt;br /&gt;
# La personnalisation des instances Drupal, de leurs bases et répertoires.&lt;br /&gt;
# La personnalisation des instances Tomcat/Pleade, de leurs connexions et répertoires.&lt;br /&gt;
# Une recette applicative complète.&lt;br /&gt;
&lt;br /&gt;
Ces opérations ne sont &#039;&#039;pas&#039;&#039; prises en charge par les phases système décrites ci-dessus à la date de cette mise à jour. Le README applicatif de TEMPLATE3 reste la référence pour la personnalisation applicative tant que ces nouvelles phases n&#039;ont pas été développées et validées.&lt;br /&gt;
&lt;br /&gt;
[[Catégorie:Infrastructure]]&lt;br /&gt;
[[Catégorie:Proxmox]]&lt;br /&gt;
[[Catégorie:Déploiement]]&lt;br /&gt;
[[Catégorie:AJLSM]]&lt;/div&gt;</summary>
		<author><name>Jlarvers</name></author>
	</entry>
</feed>