Outils pour utilisateurs

Outils du site


linux:rewinged

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
linux:rewinged [2026/09/12 07:16] – rootlinux:rewinged [2026/09/18 17:40] (Version actuelle) – [13.2 Règles personnalisées] root
Ligne 18: Ligne 18:
                       +---------------+--------------+                       +---------------+--------------+
                                       |                                       |
-                    /api*  -> :8080   |   /files/* -> :8081+                                      | HTTP 8080 (interne)
                                       v                                       v
 Forgejo                +--------------------------------+ Forgejo                +--------------------------------+
 mis/winget-manifests   | VM Debian  winget-repo         | mis/winget-manifests   | VM Debian  winget-repo         |
   manifests YAML       |                                |   manifests YAML       |                                |
-  + MSI en Git LFS     |  rewinged        :8080         | +  + MSI en Git LFS     |  rewinged :8080                | 
-        |              |    /srv/winget/manifests       | +        |              |    -manifestPath  manifests    | 
-        | git pull     |                                | +        | git pull     |    -autoInternalizePath        | 
-        | + lfs pull   |  Caddy file_server  :8081      | +        | + lfs pull   |         installers             | 
-        | timer 1 min  |    /srv/winget/installers      |+        | timer 1 min  |                                |
         +------------->|                                |         +------------->|                                |
                        +--------------------------------+                        +--------------------------------+
Ligne 34: Ligne 34:
 ^ Composant ^ Machine ^ Rôle ^ ^ Composant ^ Machine ^ Rôle ^
 | Forgejo | existante | Source de vérité : manifests YAML et installeurs MSI. | | Forgejo | existante | Source de vérité : manifests YAML et installeurs MSI. |
-| Caddy frontal | frontal existant | Terminaison TLS et routage. Aucun fichier local. | +| Caddy frontal | frontal existant | Terminaison TLS. Aucun fichier local. | 
-| rewinged | VM dédiée | API REST ''Microsoft.Rest'' consommée par winget. | +| rewinged | VM dédiée | API REST ''Microsoft.Rest'' **et** service des installeurs. |
-| Caddy local | VM dédiée | Sert les installeurs synchronisés. |+
 | Wazuh | existant | FIM sur manifests, installeurs et binaires. | | Wazuh | existant | FIM sur manifests, installeurs et binaires. |
  
Ligne 53: Ligne 52:
   * Dépôt Forgejo ''mis/winget-manifests'' avec Git LFS activé   * Dépôt Forgejo ''mis/winget-manifests'' avec Git LFS activé
   * Clé de déploiement Forgejo **en lecture seule**   * Clé de déploiement Forgejo **en lecture seule**
-  * Paquets ''git'', ''git-lfs'', ''caddy'' sur la VM+  * Paquets ''git'' et ''git-lfs'' sur la VM
  
 ===== 3. Installation de rewinged ===== ===== 3. Installation de rewinged =====
Ligne 67: Ligne 66:
 Les répertoires ''manifests'' et ''installers'' seront créés par le clone Git Les répertoires ''manifests'' et ''installers'' seront créés par le clone Git
 (section 6). (section 6).
 +
 +Le compte ''rewinged'' doit pouvoir écrire dans ''installers'' : c'est là que
 +l'auto-internalisation dépose les installeurs tiers rapatriés.
  
 ==== 3.2 Binaire ==== ==== 3.2 Binaire ====
Ligne 84: Ligne 86:
 </code> </code>
  
-<WRAP center round important> +==== 3.3 Options utiles ====
-Relever dans ''--help'' le nom exact du flag désignant le répertoire de +
-manifests, et vérifier si rewinged recharge à chaud ou s'il faut un signal +
-après un ''git pull''. Adapter les sections 3.3 et 7 en conséquence. +
-</WRAP>+
  
-==== 3.3 Service systemd ====+^ Flag ^ Rôle ^ 
 +| ''-manifestPath'' | Répertoire des manifests (défaut ''./packages'') | 
 +| ''-autoInternalize'' | Rapatrie et sert localement les installeurs distants | 
 +| ''-autoInternalizePath'' | Répertoire des installeurs servis (défaut ''./installers'') | 
 +| ''-trustedProxies'' | IP du frontal, pour journaliser l'IP réelle du client | 
 +| ''-listen'' | Adresse et port d'écoute | 
 +| ''-sourceAuthType'' | ''none'' ou ''microsoftEntraId'' | 
 +| ''-https'' | TLS assuré par rewinged, inutile derrière un frontal | 
 +| ''-logLevel'' | ''disable'', ''error'', ''warn'', ''info'', ''debug'', ''trace'' | 
 + 
 +**Deux usages de ''-autoInternalizePath''.** rewinged y dépose les installeurs 
 +qu'il rapatrie automatiquement, et sert directement tout fichier qui s'y 
 +trouve sous ''/installers/''. Les MSI synchronisés depuis Forgejo y sont donc 
 +servis sans serveur de fichiers supplémentaire. 
 + 
 +Vérifié : 
 +<code bash> 
 +curl -I http://10.0.0.20:8080/installers/mis-agent-1.2.0.msi 
 +# HTTP/1.1 200 OK 
 +# Content-Type: application/x-msi 
 +# Accept-Ranges: bytes 
 +</code> 
 + 
 +==== 3.4 Service systemd ====
  
 <file ini /etc/systemd/system/rewinged.service> <file ini /etc/systemd/system/rewinged.service>
Ligne 100: Ligne 121:
 User=rewinged User=rewinged
 Group=rewinged Group=rewinged
-ExecStart=/usr/local/bin/rewinged -listen 10.0.0.20:8080+ExecStart=/usr/local/bin/rewinged \ 
 +  -listen 10.0.0.20:8080 \ 
 +  -manifestPath /srv/winget/manifests \ 
 +  -autoInternalize \ 
 +  -autoInternalizePath /srv/winget/installers \ 
 +  -trustedProxies 10.0.0.10 \ 
 +  -logLevel info
 Restart=on-failure Restart=on-failure
 RestartSec=5 RestartSec=5
 +
 +# Journalisation vers fichier, pour collecte Wazuh en JSON natif
 +StandardOutput=append:/var/log/rewinged/rewinged.log
 +StandardError=append:/var/log/rewinged/rewinged.log
  
 # Durcissement # Durcissement
Ligne 113: Ligne 144:
 LockPersonality=true LockPersonality=true
 MemoryDenyWriteExecute=true MemoryDenyWriteExecute=true
-ReadOnlyPaths=/srv/winget+ReadOnlyPaths=/srv/winget/manifests 
 +ReadWritePaths=/srv/winget/installers /var/log/rewinged
  
 [Install] [Install]
Ligne 120: Ligne 152:
  
 <code bash> <code bash>
 +mkdir -p /var/log/rewinged
 +chown rewinged:rewinged /var/log/rewinged
 +
 systemctl daemon-reload systemctl daemon-reload
 systemctl enable --now rewinged systemctl enable --now rewinged
Ligne 125: Ligne 160:
 </code> </code>
  
-===== 4. Service de fichiers local =====+Rotation du journal :
  
-Les installeurs sont servis par un Caddy local sur la VM rewinged, en HTTP +<file - /etc/logrotate.d/rewinged> 
-sur le réseau interne. Le TLS reste la responsabilité du frontal. +/var/log/rewinged/rewinged.log { 
- +    daily 
-<file - /etc/caddy/Caddyfile> +    rotate 30 
-http://10.0.0.20:8081 { +    compress 
-    root * /srv/winget/installers +    missingok 
-    file_server { +    notifempty 
-        hide .git* +    copytruncate 
-    } +    su rewinged rewinged
-    log { +
-        output file /var/log/caddy/installers.log +
-        format json +
-    }+
 } }
 </file> </file>
  
-<code bash> +===== 4. Pare-feu de la VM =====
-systemctl enable --now caddy +
-curl -I http://10.0.0.20:8081/mis-agent-1.2.0.msi +
-</code>+
  
-Alternative à évaluer : la fonction d'internalisation de rewinged sert +Seul le frontal doit joindre rewinged.
-elle-même les installeurs, ce qui supprimerait ce composant. Vérifier le +
-chemin d'URL exposé avant de s'en remettre à elle. +
- +
-==== 4.1 Pare-feu ==== +
- +
-Seul le frontal doit joindre les deux ports.+
  
 <code bash> <code bash>
Ligne 160: Ligne 182:
 ufw default deny incoming ufw default deny incoming
 ufw allow from ${CADDY_IP} to any port 8080 proto tcp ufw allow from ${CADDY_IP} to any port 8080 proto tcp
-ufw allow from ${CADDY_IP} to any port 8081 proto tcp 
 ufw allow from 100.64.0.0/10 to any port 22 proto tcp ufw allow from 100.64.0.0/10 to any port 22 proto tcp
 ufw enable ufw enable
Ligne 173: Ligne 194:
     tls vincent@makeitsimple.be     tls vincent@makeitsimple.be
  
-    # API winget +    reverse_proxy 10.0.0.20:8080
-    reverse_proxy /api* 10.0.0.20:8080 +
- +
-    # Installeurs +
-    reverse_proxy /files/* 10.0.0.20:8081+
  
     header {     header {
Ligne 196: Ligne 213:
 interne sur chaque poste. interne sur chaque poste.
  
-<WRAP center round tip> +Un seul ''reverse_proxy'' : rewinged sert à la fois l'API sous ''/api'' et les 
-Si le Caddy local sert la racine et non ''/files/'', ajuster avec +installeurs sous ''/installers''.
-''handle_path'' côté frontal pour retirer le préfixe avant transmission. +
-</WRAP>+
  
 ===== 6. Dépôt Forgejo ===== ===== 6. Dépôt Forgejo =====
Ligne 258: Ligne 273:
 qui décide de ce que le parc installe. Le flux part toujours du serveur vers qui décide de ce que le parc installe. Le flux part toujours du serveur vers
 Forgejo. Forgejo.
 +
 +==== 7.1 Rechargement natif ====
 +
 +rewinged surveille le répertoire de manifests et recharge sans intervention.
 +Confirmé au démarrage du service :
 +
 +<code>
 +{"level":"info","message":"watching manifestPath for changes"}
 +</code>
 +
 +**Conséquence** : aucun redémarrage n'est nécessaire après une publication.
 +L'unité de synchronisation tourne donc intégralement sous le compte
 +''rewinged'', sans privilège root ni règle polkit.
 +
 +==== 7.2 Script de synchronisation ====
 +
 +<file bash /usr/local/bin/winget-sync.sh>
 +#!/bin/bash
 +#
 +# Synchronise le depot de paquets depuis Forgejo.
 +# Execute par winget-sync.timer sous le compte rewinged.
 +#
 +set -euo pipefail
 +
 +REPO_DIR="/srv/winget"
 +BRANCH="main"
 +
 +cd "$REPO_DIR"
 +
 +BEFORE=$(git rev-parse HEAD)
 +
 +git fetch origin "$BRANCH"
 +git merge --ff-only "origin/${BRANCH}"
 +git lfs pull origin
 +
 +AFTER=$(git rev-parse HEAD)
 +
 +if [ "$BEFORE" != "$AFTER" ]; then
 +    # Verification de signature : voir section 13.3
 +    if ! git verify-commit HEAD >/dev/null 2>&1; then
 +        logger -t winget-sync -p auth.crit \
 +            "SIGNATURE INVALIDE sur ${AFTER:0:8} - retour a ${BEFORE:0:8}"
 +        git reset --hard "$BEFORE"
 +        exit 1
 +    fi
 +    logger -t winget-sync "Publication verifiee: ${BEFORE:0:8} -> ${AFTER:0:8}"
 +fi
 +
 +exit 0
 +</file>
 +
 +Le bloc ''verify-commit'' suppose que les commits sont signés en GPG et que la
 +clé publique du signataire est présente dans le trousseau du compte
 +''rewinged''. Le retirer si la signature n'est pas en place — mais le conserver
 +est ce qui rend la détection Wazuh exploitable (13.3).
 +
 +<code bash>
 +chown root:root /usr/local/bin/winget-sync.sh
 +chmod 0755 /usr/local/bin/winget-sync.sh
 +</code>
 +
 +Le script appartient à root en lecture seule pour ''rewinged'' : le compte de
 +service exécute le script sans pouvoir le modifier.
 +
 +Le ''merge --ff-only'' est délibéré : si l'historique local diverge, l'opération
 +échoue au lieu de fusionner silencieusement. Une divergence signifie une
 +écriture locale sur le serveur, ce qui ne doit jamais arriver.
 +
 +Le ''logger'' trace chaque publication dans syslog. C'est ce qui permettra de
 +corréler les alertes FIM Wazuh avec une publication légitime (section 12.2).
 +
 +==== 7.3 Unités systemd ====
  
 <file ini /etc/systemd/system/winget-sync.service> <file ini /etc/systemd/system/winget-sync.service>
 [Unit] [Unit]
 Description=Sync winget manifests and installers from Forgejo Description=Sync winget manifests and installers from Forgejo
 +After=network-online.target
 +Wants=network-online.target
  
 [Service] [Service]
 Type=oneshot Type=oneshot
 User=rewinged User=rewinged
 +Group=rewinged
 WorkingDirectory=/srv/winget WorkingDirectory=/srv/winget
-ExecStart=/usr/bin/git pull --ff-only +ExecStart=/usr/local/bin/winget-sync.sh 
-ExecStart=/usr/bin/git lfs pull+ 
 +# Durcissement 
 +ProtectSystem=strict 
 +ProtectHome=true 
 +PrivateTmp=true 
 +NoNewPrivileges=true 
 +ReadWritePaths=/srv/winget
 </file> </file>
  
Ligne 278: Ligne 374:
 OnBootSec=1min OnBootSec=1min
 OnUnitActiveSec=1min OnUnitActiveSec=1min
 +AccuracySec=10s
  
 [Install] [Install]
Ligne 290: Ligne 387:
 </code> </code>
  
-Le ''--ff-only'' est délibéré : si l'historique local diverge, le pull échoue +==== 7.4 Propriété des fichiers ====
-au lieu de fusionner silencieusement. Une divergence signifie une écriture +
-locale, ce qui ne doit jamais arriver.+
  
-<WRAP center round important> +Le clone doit appartenir à ''rewinged'' de bout en bout. Un clone effectué en 
-''ReadOnlyPaths=/srv/winget'' dans l'unité rewinged empêche le service de +root bloque la synchronisation. 
-modifier le dépôt, mais n'affecte pas ''winget-sync'' qui est une unité + 
-distincte. Vérifier que le pull aboutit après le premier démarrage. +<code bash> 
-</WRAP>+# Preparation, en root 
 +mkdir -p /srv/winget 
 +chown rewinged:rewinged /srv/winget 
 + 
 +# Clone, sous le compte de service 
 +sudo -u rewinged git clone git@forgejo.makeitsimple.be:mis/winget-manifests.git /srv/winget 
 +</code> 
 + 
 +Rattrapage si le clone a déjà été fait en root : 
 + 
 +<code bash> 
 +chown -R rewinged:rewinged /srv/winget 
 +sudo -u rewinged git -C /srv/winget status 
 +</code> 
 + 
 +Git refuse d'opérer sur un dépôt dont le propriétaire diffère de l'utilisateur 
 +courant (''dubious ownership''). C'est le garde-fou qui signale un ''chown'' 
 +oublié. 
 + 
 +Vérification décisive : 
 + 
 +<code bash> 
 +sudo -u rewinged /usr/local/bin/winget-sync.sh 
 +</code> 
 + 
 +Si elle passe, le timer passera aussi. 
 + 
 +==== 7.5 Variante avec redémarrage ==== 
 + 
 +À n'utiliser que si le rechargement natif s'avère insuffisant — par exemple 
 +après une montée de version de rewinged qui modifierait ce comportement. 
 + 
 +Autorisation ciblée dans sudoers : 
 + 
 +<file - /etc/sudoers.d/winget-sync> 
 +rewinged ALL=(root) NOPASSWD: /usr/bin/systemctl try-reload-or-restart rewinged 
 +</file> 
 + 
 +<code bash> 
 +visudo -c -f /etc/sudoers.d/winget-sync 
 +chmod 0440 /etc/sudoers.d/winget-sync 
 +</code> 
 + 
 +Ligne à ajouter dans le bloc conditionnel du script : 
 + 
 +<code bash> 
 +    sudo /usr/bin/systemctl try-reload-or-restart rewinged 
 +</code> 
 + 
 +**Redémarrer uniquement sur changement de HEAD.** À raison de 1440 exécutions 
 +par jour, un redémarrage systématique pollue les journaux et provoque des 
 +micro-coupures pendant les téléchargements.
  
 ===== 8. Format d'un manifest ===== ===== 8. Format d'un manifest =====
Ligne 313: Ligne 459:
   - Architecture: x64   - Architecture: x64
     InstallerType: msi     InstallerType: msi
-    InstallerUrl: https://repo.makeitsimple.be/files/mis-agent-1.2.0.msi+    InstallerUrl: https://repo.makeitsimple.be/installers/mis-agent-1.2.0.msi
     InstallerSha256: A1B2C3D4E5F6...     InstallerSha256: A1B2C3D4E5F6...
     Scope: machine     Scope: machine
Ligne 336: Ligne 482:
 sur le PATH. sur le PATH.
  
-===== 9. Extraction des codes MSI =====+===== 9. Convention pour les paquets par client ===== 
 + 
 +RustDesk est publié en un paquet par client : le mot de passe d'accès 
 +non-surveillé est préconfiguré dans le MSI et diffère d'un client à l'autre. 
 + 
 +==== 9.1 Nommage ==== 
 + 
 +<code> 
 +PackageIdentifier: Rustdesk.<CodeClient> 
 +</code> 
 + 
 +  * manifest : ''manifests/r/Rustdesk/<CodeClient>/<version>/Rustdesk.<CodeClient>.yaml'' 
 +  * installeur : ''installers/rustdesk-<codeclient>.msi'' 
 + 
 +==== 9.2 Conséquence opérationnelle ==== 
 + 
 +À chaque version de RustDesk, autant de MSI à régénérer et de manifests à 
 +republier qu'il y a de clients. À l'échelle de la centaine, la publication 
 +doit être scriptée : un outil qui parcourt la liste des clients, appelle 
 +''Get-MsiCodes'' (section 10.1), calcule le SHA256 et génère le YAML. 
 + 
 +La saisie manuelle n'est pas tenable et expose au risque de coller le GUID 
 +d'une version précédente. 
 + 
 +==== 9.3 Visibilité ==== 
 + 
 +La source n'a pas de notion de périmètre : tout poste ayant enregistré 
 +''mis-repo'' peut énumérer l'ensemble des paquets, donc la liste des codes 
 +clients. Sans conséquence sur l'accès aux machines, mais à connaître. 
 + 
 +==== 9.4 Alternative : paquet unique ==== 
 + 
 +Le paquet par client existe parce que le mot de passe non-surveillé est 
 +préconfiguré dans le MSI. Ce mot de passe peut aussi être posé **après** 
 +installation, ce qui autorise un paquet unique pour tout le parc. 
 + 
 +=== Ce qui n'est pas possible === 
 + 
 +Le mot de passe permanent **ne se propage pas par API ni par stratégie**. 
 +C'est un secret local à la machine. La demande d'en faire un paramètre de 
 +stratégie Pro est ouverte depuis 2023 et n'a pas abouti. 
 + 
 +Ne pas confondre trois objets distincts : 
 + 
 +^ Élément ^ Où il vit ^ Comment il se pose ^ 
 +| Mot de passe permanent | Sur la machine, haché localement | ''RustDesk.exe --password'' en local | 
 +| Mot de passe du carnet | Côté serveur Pro | ''--assign --address_book_password'' | 
 +| Stratégie Pro | Côté serveur Pro | Réglages client, **hors** mot de passe | 
 + 
 +Le premier authentifie les connexions entrantes. Le second est celui que le 
 +client technicien utilise pour remplir automatiquement le champ. 
 + 
 +=== Le flux en deux temps === 
 + 
 +Le secret naît sur la machine, puis remonte vers le serveur. 
 + 
 +<file powershell onboard-rustdesk.ps1> 
 +$rd = "C:\Program Files\RustDesk\RustDesk.exe" 
 + 
 +# 1. Generer un mot de passe propre a CETTE machine 
 +$pw = -join ((48..57)+(65..90)+(97..122) | Get-Random -Count 20 | % {[char]$_}) 
 + 
 +# 2. Le poser localement 
 +& $rd --password $pw 
 + 
 +# 3. Recuperer l'ID attribue 
 +$id = (& $rd --get-id).Trim() 
 + 
 +# 4. Rattacher au carnet du client et y stocker le mot de passe 
 +& $rd --assign ` 
 +    --token $env:RUSTDESK_API_TOKEN ` 
 +    --address_book_name "Client-$ClientCode" ` 
 +    --address_book_alias $env:COMPUTERNAME ` 
 +    --address_book_password $pw 
 + 
 +# 5. Archiver dans Vaultwarden (ID + mot de passe) 
 +</file> 
 + 
 +=== Ce que cela change === 
 + 
 +  * **Un seul manifest** RustDesk pour l'ensemble du parc 
 +  * **Un mot de passe par machine** au lieu d'un par client : la fuite d'un 
 +    secret n'expose plus tout le parc d'un client 
 +  * Plus de régénération de MSI à chaque release 
 +  * Prérequis : Server Pro 1.5.8 et client 1.4.1 pour ''--address_book_alias'' 
 + 
 +=== À valider avant de basculer === 
 + 
 +<WRAP center round important> 
 +Un dysfonctionnement de ''RustDesk.exe --password'' sous Windows a été 
 +signalé en mai 2025 : la commande retourne sans effet. Tester sur un poste 
 +témoin, service arrêté puis démarré, avant de bâtir l'onboarding dessus. 
 +</WRAP> 
 + 
 +Vérifier également que le token API utilisé porte les seules permissions 
 +''Device'' et ''Address Book'', et qu'il n'est pas écrit en clair dans le 
 +script — le passer par variable d'environnement ou le récupérer depuis 
 +Vaultwarden au moment de l'exécution. 
 + 
 +===== 10. Extraction des codes MSI =====
  
 Le ''ProductCode'' change à chaque version d'un MSI bien construit ; Le ''ProductCode'' change à chaque version d'un MSI bien construit ;
Ligne 343: Ligne 588:
 logiciels déjà installés depuis d'anciens paquets custom. logiciels déjà installés depuis d'anciens paquets custom.
  
-==== 9.1 Depuis un fichier MSI ====+==== 10.1 Depuis un fichier MSI ====
  
 À exécuter sur la machine de build (Windows). Lecture seule, sans installation À exécuter sur la machine de build (Windows). Lecture seule, sans installation
Ligne 381: Ligne 626:
 tourne pas sur la VM Debian. tourne pas sur la VM Debian.
  
-==== 9.2 Depuis un poste où le logiciel est installé ====+==== 10.2 Depuis un poste où le logiciel est installé ====
  
 Pour recenser les GUID en circulation dans le parc : Pour recenser les GUID en circulation dans le parc :
Ligne 402: Ligne 647:
 </WRAP> </WRAP>
  
-==== 9.3 Automatisation ====+==== 10.3 Automatisation ====
  
 L'agent d'inventaire devrait remonter le ProductCode de chaque logiciel L'agent d'inventaire devrait remonter le ProductCode de chaque logiciel
Ligne 408: Ligne 653:
 ''AppsAndFeaturesEntries'' à renseigner, sans interroger les postes un par un. ''AppsAndFeaturesEntries'' à renseigner, sans interroger les postes un par un.
  
-===== 10. Workflow de publication =====+===== 11. Workflow de publication =====
  
   - Construire l'installeur   - Construire l'installeur
Ligne 423: Ligne 668:
 </code> </code>
  
-===== 11. Configuration des postes =====+===== 12. Configuration des postes =====
  
-==== 11.1 Enregistrement de la source ====+==== 12.1 Enregistrement de la source ====
  
 <code powershell> <code powershell>
Ligne 436: Ligne 681:
 l'utilisateur courant et reste invisible à l'agent tournant en service. l'utilisateur courant et reste invisible à l'agent tournant en service.
  
-==== 11.2 Winget en contexte SYSTEM ====+==== 12.2 Winget en contexte SYSTEM ====
  
 ''winget'' n'est pas dans le PATH pour le compte SYSTEM. Résoudre le chemin ''winget'' n'est pas dans le PATH pour le compte SYSTEM. Résoudre le chemin
Ligne 450: Ligne 695:
 un prompt bloque le processus indéfiniment. un prompt bloque le processus indéfiniment.
  
-==== 11.3 Adoption du parc existant ====+==== 12.3 Adoption du parc existant ====
  
 Un paquet installé autrement que depuis la source privée n'est pas reconnu Un paquet installé autrement que depuis la source privée n'est pas reconnu
Ligne 461: Ligne 706:
 À valider sur un poste témoin **avant** de dimensionner la campagne. À valider sur un poste témoin **avant** de dimensionner la campagne.
  
-==== 11.4 Compatibilité ====+==== 12.4 Compatibilité ====
  
 ^ Système ^ App Installer ^ ^ Système ^ App Installer ^
Ligne 472: Ligne 717:
 le canal unique ou s'il faut un second canal. le canal unique ou s'il faut un second canal.
  
-===== 12. Surveillance Wazuh =====+===== 13. Surveillance Wazuh =====
  
-==== 12.1 FIM ====+Trois sources distinctes : l'intégrité des fichiers, le journal applicatif de 
 +rewinged, et l'état des services.
  
-<file xml ossec.conf> +==== 13.1 Configuration de l'agent ==== 
-<syscheck> + 
-  <directories check_all="yes" realtime="yes" report_changes="yes"> +<file xml /var/ossec/etc/ossec.conf> 
-    /srv/winget/manifests +<ossec_config> 
-  </directories> + 
-  <directories check_all="yes" realtime="yes"> +  <!-- Integrite des fichiers --> 
-    /srv/winget/installers +  <syscheck> 
-  </directories> +    <disabled>no</disabled> 
-  <directories check_all="yes" realtime="yes"> +    <frequency>3600</frequency> 
-    /usr/local/bin + 
-  </directories> +    <!-- Manifests : decident de ce que le parc installe --> 
-</syscheck>+    <directories check_all="yes" realtime="yes" report_changes="yes" 
 +                 tags="winget,manifests">/srv/winget/manifests</directories> 
 + 
 +    <!-- Installeurs : les binaires servis aux postes --> 
 +    <directories check_all="yes" realtime="yes" 
 +                 tags="winget,installers">/srv/winget/installers</directories> 
 + 
 +    <!-- Binaire rewinged et script de synchronisation --> 
 +    <directories check_all="yes" realtime="yes" 
 +                 tags="winget,binaries">/usr/local/bin</directories> 
 + 
 +    <!-- Unites systemd du service --> 
 +    <directories check_all="yes" realtime="yes" 
 +                 tags="winget,systemd">/etc/systemd/system</directories> 
 + 
 +    <!-- Bruit git interne --> 
 +    <ignore type="sregex">^/srv/winget/\.git/</ignore> 
 +  </syscheck> 
 + 
 +  <!-- Journal applicatif rewinged, deja en JSON --> 
 +  <localfile> 
 +    <log_format>json</log_format> 
 +    <location>/var/log/rewinged/rewinged.log</location> 
 +  </localfile> 
 + 
 +  <!-- Etat des services, toutes les 5 minutes --> 
 +  <localfile> 
 +    <log_format>full_command</log_format> 
 +    <command>systemctl is-active rewinged winget-sync.timer | tr '\n' ' '</command> 
 +    <alias>winget-services</alias> 
 +    <frequency>300</frequency> 
 +  </localfile> 
 + 
 +</ossec_config>
 </file> </file>
  
-==== 12.2 Réduction du bruit ====+Le journal de ''winget-sync'' passe par ''logger'', donc par syslog, déjà 
 +collecté par la configuration Wazuh par défaut.
  
-La FIM se déclenche à chaque synchronisation légitime. Pour distinguer le +==== 13.2 Règles personnalisées ==== 
-légitime de l'anormal :+ 
 +<file xml /var/ossec/etc/rules/local_rules.xml> 
 +<group name="winget,rewinged,"> 
 + 
 +  <rule id="100600" level="0"> 
 +    <decoded_as>json</decoded_as> 
 +    <location>/var/log/rewinged/rewinged.log</location> 
 +    <description>rewinged: evenement applicatif</description> 
 +  </rule> 
 + 
 +  <rule id="100601" level="7"> 
 +    <if_sid>100600</if_sid> 
 +    <field name="level">error</field> 
 +    <description>rewinged: erreur applicative</description> 
 +  </rule> 
 + 
 +  <rule id="100602" level="10"> 
 +    <if_sid>100601</if_sid> 
 +    <field name="message">ingestManifests</field> 
 +    <description>rewinged: echec ingestion des manifests - $(message)</description> 
 +  </rule> 
 + 
 +  <rule id="100610" level="3"> 
 +    <program_name>winget-sync</program_name> 
 +    <match>Publication verifiee</match> 
 +    <description>winget: publication synchronisee et verifiee</description> 
 +  </rule> 
 + 
 +  <rule id="100611" level="14"> 
 +    <program_name>winget-sync</program_name> 
 +    <match>SIGNATURE INVALIDE</match> 
 +    <description>winget: signature invalide - synchronisation annulee</description> 
 +    <group>attack,</group> 
 +  </rule> 
 + 
 +  <rule id="100612" level="10" frequency="5" timeframe="1800"> 
 +    <if_matched_sid>100601</if_matched_sid> 
 +    <description>winget: erreurs applicatives repetees</description> 
 +  </rule> 
 + 
 +  <rule id="100620" level="3"> 
 +    <if_group>syscheck</if_group> 
 +    <field name="file">/srv/winget/manifests/</field> 
 +    <description>winget: manifest modifie - $(file)</description> 
 +  </rule> 
 + 
 +  <rule id="100621" level="12"> 
 +    <if_group>syscheck</if_group> 
 +    <field name="file">/srv/winget/installers/</field> 
 +    <description>winget: installeur modifie - $(file)</description> 
 +    <group>attack,</group> 
 +  </rule> 
 + 
 +  <rule id="100622" level="14"> 
 +    <if_group>syscheck</if_group> 
 +    <field name="file">/usr/local/bin/rewinged</field> 
 +    <description>winget: binaire rewinged modifie - $(file)</description> 
 +    <group>attack,</group> 
 +  </rule> 
 + 
 +  <rule id="100630" level="0"> 
 +    <location>winget-services</location> 
 +    <description>winget: releve d'etat des services</description> 
 +  </rule> 
 + 
 +  <rule id="100631" level="10"> 
 +    <if_sid>100630</if_sid> 
 +    <regex>inactive|failed|unknown</regex> 
 +    <description>winget: service rewinged ou timer arrete</description> 
 +  </rule> 
 + 
 +</group> 
 +</file> 
 + 
 +<WRAP center round important> 
 +Les identifiants 100600–100631 sont donnés à titre indicatif. Les adapter à 
 +la numérotation des règles personnalisées déjà en place. 
 +</WRAP> 
 + 
 +==== 13.3 Traiter le bruit FIM ==== 
 + 
 +La FIM se déclenche à chaque publication légitime. Wazuh ne sait pas exprimer 
 +nativement « alerter sauf si précédé de tel événement », il faut donc déplacer 
 +le contrôle plutôt que tenter de corréler. 
 + 
 +**Approche retenue** : la signature GPG des commits est le contrôle réel. 
 + 
 +  - Les commits de publication sont signés ; la clé publique du signataire est 
 +    dans le trousseau du compte ''rewinged'' 
 +  - ''winget-sync.sh'' vérifie la signature et annule la synchronisation en cas 
 +    d'échec (section 7.2) 
 +  - La FIM sur ''manifests'' reste **informative** (niveau 3) : elle documente, 
 +    elle n'alerte pas 
 +  - L'alerte forte porte sur la signature invalide (100611, niveau 14) 
 + 
 +Une modification de manifest effectuée directement sur le serveur ne passe pas 
 +par un commit, donc ne déclenche pas 100611 — mais elle sera écrasée au 
 +prochain ''merge --ff-only'', et la FIM en garde la trace. 
 + 
 +Les installeurs et les binaires, eux, ne changent pas hors publication : leurs 
 +règles restent à niveau élevé. 
 + 
 +==== 13.4 Mise en place de la signature ==== 
 + 
 +Côté poste de publication : 
 + 
 +<code bash> 
 +git config --global user.signingkey <ID_CLE> 
 +git config --global commit.gpgsign true 
 +gpg --export --armor <ID_CLE> > mis-publication.pub 
 +</code> 
 + 
 +Côté serveur rewinged : 
 + 
 +<code bash> 
 +sudo -u rewinged gpg --import mis-publication.pub 
 +sudo -u rewinged gpg --edit-key <ID_CLE> trust   # niveau ultimate 
 +sudo -u rewinged git -C /srv/winget verify-commit HEAD 
 +</code>
  
-  * signer les commits en GPG et vérifier la signature dans ''winget-sync'' +Idéalement la clé de signature réside sur une YubiKey, cohérent avec 
-    avant application — un fichier modifié sans commit signé devient alors une +l'autorité de certification SSH déjà en place.
-    alerte non ambiguë +
-  * à défaut, corréler avec les logs de ''winget-sync.service''+
  
-==== 12.3 Alertes complémentaires ====+==== 13.5 Ce qui reste non couvert ====
  
-  * arrêt des services ''rewinged'' ou ''caddy'' +  * **Publication légitime mais erronée** — un mauvais ''PackageIdentifier'' 
-  * échecs répétés de ''winget-sync.timer'' — un dépôt figé est un mode de +    ou un SHA256 incorrect signé de bonne foi passe toutes les vérifications. 
-    panne silencieux +    Le garde-fou est la revue de la PR, pas la détection. 
-  * volumétrie anormale de téléchargements sur ''/files/'' +  * **Compromission du poste de publication** — si la clé de signature est 
-  * saturation disque de la VM (croissance LFS)+    utilisable par un attaquant, la chaîne entière est valide de son point de 
 +    vue. D'où la YubiKey. 
 +  * **Saturation disque** — à surveiller côté Zabbix plutôt que Wazuh, la 
 +    croissance LFS étant progressive et prévisible.
  
-===== 13. Points ouverts =====+===== 14. Points ouverts =====
  
 ^ Sujet ^ Action ^ ^ Sujet ^ Action ^
-| Flags rewinged | Confirmer le nom du flag de répertoire et le rechargement à chaud via ''--help'' | +| Auto-internalisation | Valider le rapatriement des installeurs tiers depuis les URL éditeur |
-| Internalisation | Évaluer si rewinged peut remplacer le Caddy local (section 4) |+
 | Bug de matching | Tester sur un poste témoin avec un logiciel préinstallé | | Bug de matching | Tester sur un poste témoin avec un logiciel préinstallé |
 | Server 2019/2022 | Inventorier la proportion dans le parc | | Server 2019/2022 | Inventorier la proportion dans le parc |
 | Upgrade RustDesk | Vérifier que la mise à jour préserve ''RustDesk2.toml'' et le mot de passe permanent | | Upgrade RustDesk | Vérifier que la mise à jour préserve ''RustDesk2.toml'' et le mot de passe permanent |
 +| ''--password'' sous Windows | Tester le réglage du mot de passe en ligne de commande (9.4) avant d'envisager le paquet unique |
 | Rétention LFS | Définir une politique de purge des anciennes versions d'installeurs | | Rétention LFS | Définir une politique de purge des anciennes versions d'installeurs |
 | Quota Forgejo | Dimensionner le stockage LFS et surveiller sa croissance | | Quota Forgejo | Dimensionner le stockage LFS et surveiller sa croissance |
  
-===== 14. Références =====+===== 15. Références =====
  
   * [[https://github.com/jantari/rewinged|rewinged — dépôt GitHub]]   * [[https://github.com/jantari/rewinged|rewinged — dépôt GitHub]]
   * [[https://learn.microsoft.com/windows/package-manager/|Documentation Windows Package Manager]]   * [[https://learn.microsoft.com/windows/package-manager/|Documentation Windows Package Manager]]
   * [[https://rustdesk.com/docs/en/self-host/rustdesk-server-pro/console/|RustDesk Server Pro — console et tokens API]]   * [[https://rustdesk.com/docs/en/self-host/rustdesk-server-pro/console/|RustDesk Server Pro — console et tokens API]]
linux/rewinged.1789197393.txt.gz · Dernière modification : de root