Documente les groupes de sécurité et le résultat de l'audit machine
This commit is contained in:
1 parent
b48c4c5412
commit
5f1d3438a2
1 file changed
+127
-99
@@ -1,99 +1,127 @@
|
|||||||
**form-gpresult-computer**
|
# Audit GPResult — Ordinateur
|
||||||
Paquet WAPT d'audit des stratégies de groupe appliquées à l'ordinateur. Il collecte un export XML de GPResult et enregistre un résultat structuré dans **`audit-gpresult.computer-gpo`**.
|
|
||||||
Le nom `form-gpresult-computer` est proposé pour identifier ce paquet dans le dépôt, en complément de `form-gpresult-user`. Si le paquet machine existe déjà sous un autre nom, conserver son identité actuelle.
|
Paquet WAPT d'audit des GPO et des groupes de sécurité de l'ordinateur. Le résultat structuré est enregistré dans **`audit-gpresult.computer-gpo`**.
|
||||||
**Description pour le dépôt**
|
|
||||||
**Libellé proposé :** Audit GPO — Ordinateur
|
## Fonctionnement
|
||||||
Ligne à reporter dans le champ `description` du fichier `WAPT/control` existant :
|
|
||||||
```
|
1. `install()` ne réalise aucune action.
|
||||||
description: Audit des GPO machine : domaine, site, listes des GPO appliquees et non appliquees et compteurs dans audit-gpresult.computer-gpo.
|
2. `audit()` supprime un éventuel rapport temporaire précédent, puis lance GPResult avec un délai maximal de 120 secondes :
|
||||||
|
|
||||||
```
|
```text
|
||||||
Cette ligne est également fournie dans `WAPT/description.txt`. Ce fichier n'est pas un contrôle WAPT complet : conserver les autres métadonnées du paquet existant.
|
gpresult.exe /SCOPE COMPUTER /X "<rapport.xml>" /F
|
||||||
**Fonctionnement**
|
```
|
||||||
1. L'installation appelle `install()`, volontairement vide.
|
|
||||||
2. L'audit supprime, s'il existe, le rapport temporaire précédent.
|
3. Le script analyse la section `ComputerResults`, collecte l'identité du poste, classe les GPO et les groupes de sécurité.
|
||||||
3. Il lance GPResult depuis le chemin construit avec `makepath(system32(), "gpresult.exe")`, avec les options `/SCOPE COMPUTER /X "<rapport.xml>" /F` et un délai maximal de 120 secondes.
|
4. Il transmet un dictionnaire à `WAPT.write_audit_data_if_changed`, avec `keep_days=365` et `max_count=1`.
|
||||||
4. Il recherche la section XML `ComputerResults`, extrait les informations et classe les GPO.
|
5. La suppression du rapport est tentée dans `finally`, après succès comme après erreur.
|
||||||
5. Il enregistre directement un dictionnaire avec `WAPT.write_audit_data_if_changed`.
|
|
||||||
6. Il tente de supprimer le rapport temporaire dans un bloc `finally`.
|
Le chemin de GPResult est construit avec `makepath(system32(), "gpresult.exe")`. L'audit consulte les données RSoP disponibles, sans lancer de `gpupdate` ni modifier les stratégies. Aucune session utilisateur active n'est nécessaire. Les GPO et groupes du contexte utilisateur sont collectés par le paquet utilisateur séparé.
|
||||||
Le paquet consulte les données RSoP disponibles. Il ne lance pas de `gpupdate` et ne modifie pas les stratégies de groupe. Il n'a pas besoin d'une session utilisateur active et ne collecte pas les GPO utilisateur.
|
|
||||||
**Prérequis**
|
## Prérequis
|
||||||
- Poste Windows disposant de GPResult au chemin construit par les fonctions WAPT utilisées.
|
|
||||||
- Agent WAPT fournissant `setuphelpers` et `WAPT.write_audit_data_if_changed`.
|
- Poste Windows disposant de GPResult et de données RSoP machine accessibles.
|
||||||
- Données RSoP machine disponibles et droits suffisants dans le contexte de l'agent pour les consulter.
|
- Agent WAPT fournissant `setuphelpers` et `WAPT.write_audit_data_if_changed`.
|
||||||
- Accès en lecture et écriture au répertoire temporaire du contexte d'exécution.
|
- Droits suffisants pour consulter le RSoP machine et écrire dans le répertoire temporaire du contexte d'exécution.
|
||||||
**Données produites**
|
|
||||||
**Catégorie :** `audit-gpresult` — **Clé :** `computer-gpo`.
|
## Données produites
|
||||||
Exemple illustratif :
|
|
||||||
```
|
Catégorie : `audit-gpresult` ; clé : `computer-gpo`.
|
||||||
{
|
|
||||||
"status": "OK",
|
Exemple illustratif d'un résultat de succès :
|
||||||
"computer": {
|
|
||||||
"name": "POSTE01",
|
```json
|
||||||
"domain": "exemple.lan",
|
{
|
||||||
"site": "Default-First-Site-Name"
|
"status": "OK",
|
||||||
},
|
"computer": {
|
||||||
"summary": {
|
"name": "POSTE01",
|
||||||
"applied_gpo_count": 2,
|
"account": "EXEMPLE\\POSTE01$",
|
||||||
"denied_gpo_count": 1,
|
"account_domain": "EXEMPLE",
|
||||||
"total_gpo_count": 3
|
"domain": "exemple.lan",
|
||||||
},
|
"site": "Default-First-Site-Name"
|
||||||
"applied_gpos": [
|
},
|
||||||
"Local Group Policy",
|
"summary": {
|
||||||
"Default Domain Policy"
|
"applied_gpo_count": 2,
|
||||||
],
|
"denied_gpo_count": 1,
|
||||||
"denied_gpos": [
|
"total_gpo_count": 3,
|
||||||
"GPO non appliquee"
|
"domain_group_count": 1,
|
||||||
]
|
"local_group_count": 1,
|
||||||
}
|
"system_group_count": 1,
|
||||||
|
"other_group_count": 0
|
||||||
```
|
},
|
||||||
|
"applied_gpos": ["Local Group Policy", "Default Domain Policy"],
|
||||||
| | |
|
"denied_gpos": ["GPO non appliquee"],
|
||||||
| - | - |
|
"domain_groups": ["EXEMPLE\\Domain Computers"],
|
||||||
| **Champ** | **Signification** |
|
"security_groups": {
|
||||||
| `status` | État de la collecte, pas un verdict de conformité. |
|
"domain": ["EXEMPLE\\Domain Computers"],
|
||||||
| `computer.name` | Nom du poste issu de `COMPUTERNAME`. |
|
"local": ["BUILTIN\\Users"],
|
||||||
| `computer.domain` | Premier texte `DomainName` trouvé dans le sous-arbre machine, sinon premier texte `Domain`. |
|
"system": ["NT AUTHORITY\\Authenticated Users"],
|
||||||
| `computer.site` | Premier texte `Site` trouvé dans le sous-arbre machine. |
|
"other": []
|
||||||
| `summary.applied_gpo_count` | Nombre d'entrées retenues comme appliquées. |
|
}
|
||||||
| `summary.denied_gpo_count` | Nombre d'entrées retenues comme non appliquées. |
|
}
|
||||||
| `summary.total_gpo_count` | Somme des deux compteurs. |
|
```
|
||||||
| `applied_gpos` | Noms des GPO classées comme appliquées, dans l'ordre de collecte. |
|
|
||||||
| `denied_gpos` | Noms des GPO classées comme non appliquées, dans l'ordre de collecte. |
|
| Champ | Signification |
|
||||||
|
| --- | --- |
|
||||||
|
| `status` | État de la collecte ; ce n'est pas un verdict de conformité. |
|
||||||
Les champs de domaine et de site restent des chaînes vides si aucune valeur n'est trouvée. La recherche de texte est récursive ; elle conserve le comportement du script fourni.
|
| `computer.name` | Nom du poste issu de `COMPUTERNAME`. |
|
||||||
**Règles de classement conservées**
|
| `computer.account` | Premier texte `Name` trouvé dans `ComputerResults`, utilisé comme compte RSoP machine. |
|
||||||
Une GPO est considérée comme appliquée si `Enabled`, `IsValid` et `FilterAllowed` sont vrais et si `AccessDenied` est faux. Toutes les autres entrées retenues sont placées dans `denied_gpos`.
|
| `computer.account_domain` | Préfixe du compte avant `\`, généralement au format NetBIOS ; vide si aucun préfixe n'est présent. |
|
||||||
Les valeurs `true`, `1`, `yes` et `oui`, sans distinction de casse, sont interprétées comme vraies. Toute autre valeur, y compris un champ absent, est interprétée comme fausse. Un `AccessDenied` absent est donc considéré comme faux, tandis qu'un `Enabled`, `IsValid` ou `FilterAllowed` absent empêche le classement en GPO appliquée.
|
| `computer.domain` | Premier texte `DomainName`, sinon premier texte `Domain`, dans le sous-arbre machine. |
|
||||||
**`denied_gpos` signifie ici « GPO non appliquées »**, et pas uniquement « refus de sécurité ». La liste peut notamment inclure des entrées filtrées, désactivées ou invalides.
|
| `computer.site` | Premier texte `Site` trouvé dans le sous-arbre machine. |
|
||||||
La recherche des balises `GPO` est récursive. Les doublons sont éliminés selon le triplet `(nom, version annuaire, version SYSVOL)` ; un même nom peut donc apparaître plusieurs fois si les versions diffèrent. Les entrées sans nom sont ignorées. Les compteurs décrivent les entrées retenues par cet algorithme, pas un inventaire de toutes les GPO du domaine.
|
| `summary.applied_gpo_count` / `summary.denied_gpo_count` | Nombre de GPO retenues dans chaque liste. |
|
||||||
**Statuts**
|
| `summary.total_gpo_count` | Somme des deux compteurs de GPO. |
|
||||||
|
| `summary.domain_group_count` / `summary.local_group_count` / `summary.system_group_count` / `summary.other_group_count` | Nombre de groupes retenus dans chaque catégorie. |
|
||||||
| | |
|
| `applied_gpos` / `denied_gpos` | Noms des GPO, dans l'ordre de collecte. |
|
||||||
| - | - |
|
| `domain_groups` | Même liste que `security_groups.domain`, pour faciliter le reporting. |
|
||||||
| **Retour d'audit** | **Situation** |
|
| `security_groups` | Groupes de sécurité répartis entre `domain`, `local`, `system` et `other`. |
|
||||||
| `OK` | Export, analyse et enregistrement terminés, même si des GPO non appliquées sont présentes. |
|
|
||||||
| `ERROR` | Échec de la commande, fichier absent, XML invalide, section machine absente ou autre exception capturée. |
|
La recherche de texte est récursive et ignore les namespaces XML. Les informations non trouvées restent des chaînes vides. Le champ `computer.domain` peut contenir un nom DNS lorsqu'il est fourni par l'export ; le repli sur `Domain` ne garantit pas ce format.
|
||||||
|
|
||||||
|
## Classement des GPO
|
||||||
En cas d'erreur, la même clé reçoit un objet contenant `status: ERROR` et `message`. Les champs du précédent succès ne sont pas recopiés. Les consommateurs doivent lire `status` avant d'accéder aux listes et compteurs.
|
|
||||||
Les paramètres d'enregistrement sont `keep_days=365` et `max_count=1`. Aucun statut `WARNING` n'est utilisé dans cette version. Une section `ComputerResults` présente mais sans GPO retenue produit un résultat `OK` avec des compteurs à zéro.
|
Une GPO est appliquée si `Enabled`, `IsValid` et `FilterAllowed` sont vrais et si `AccessDenied` est faux. Toutes les autres entrées retenues vont dans `denied_gpos` : cette liste couvre les GPO non appliquées, y compris les GPO filtrées, désactivées ou invalides.
|
||||||
**Déploiement**
|
|
||||||
1. Copier le `setup.py` fourni dans les sources du paquet existant.
|
Les valeurs `true`, `1`, `yes` et `oui`, sans distinction de casse, sont vraies. Toute autre valeur ou un champ absent est faux. Un indicateur positif absent empêche donc le classement comme GPO appliquée ; un `AccessDenied` absent est considéré comme faux.
|
||||||
2. Reporter la description dans `WAPT/control` et incrémenter la version selon les conventions du dépôt.
|
|
||||||
3. Reconstruire, signer et téléverser le paquet.
|
La recherche des balises `GPO` est récursive. Les entrées sans nom sont ignorées et les doublons sont éliminés selon `(nom, VersionDirectory, VersionSysvol)`. Un nom peut apparaître plusieurs fois si les versions diffèrent. Les listes de GPO ne sont pas triées. Les compteurs décrivent les entrées retenues, sans constituer un inventaire de toutes les GPO du domaine.
|
||||||
4. Déployer la version, puis lancer l'audit depuis WAPT.
|
|
||||||
5. Consulter `audit-gpresult.computer-gpo`.
|
## Classement des groupes de sécurité
|
||||||
La fréquence des audits dépend de la configuration WAPT existante ; le script ne crée pas de planification.
|
|
||||||
**Dépannage et limites de cette version**
|
Les groupes sont extraits des balises `SecurityGroup` du RSoP, sans requête LDAP supplémentaire. Le classement utilise les préfixes des noms, dans cet ordre :
|
||||||
- Consulter le journal de l'audit pour connaître l'erreur GPResult ou XML.
|
|
||||||
- Vérifier l'accès à GPResult, les droits de collecte machine et les données RSoP.
|
| Catégorie | Règle |
|
||||||
- Le rapport temporaire utilise un nom fixe : `wapt-gpresult-computer.xml` dans `tempfile.gettempdir()`. Éviter des exécutions concurrentes de ce même audit dans le même répertoire temporaire.
|
| --- | --- |
|
||||||
- Le nettoyage est tenté dans tous les cas ; un échec de suppression est ignoré et peut laisser le rapport sur disque.
|
| `system` | Préfixe `NT AUTHORITY\`. |
|
||||||
- La collecte restitue les données disponibles, sans forcer leur actualisation.
|
| `local` | Préfixe `BUILTIN\` ou nom du poste suivi de `\`. |
|
||||||
**Contenu**
|
| `domain` | Préfixe du compte RSoP suivi de `\`, si ce préfixe est non vide et différent du nom du poste. |
|
||||||
- `setup.py` : code fourni, enrichi de commentaires et de docstrings, sans modification de logique.
|
| `other` | Toutes les autres identités. |
|
||||||
- `README.md` : fonctionnement, interprétation, prérequis et exploitation.
|
|
||||||
- `WAPT/description.txt` : ligne de description pour le contrôle existant
|
Les comparaisons et la déduplication des noms ignorent la casse. Les entrées sans nom sont ignorées ; chaque liste est triée alphabétiquement sans distinction de casse.
|
||||||
|
|
||||||
|
Ce classement repose sur les noms présents dans l'export, sans validation du domaine par SID ou LDAP. Les noms localisés ou les groupes d'un autre domaine peuvent rester dans `other`. Les listes reflètent les données RSoP collectées ; elles ne constituent pas un inventaire exhaustif des groupes AD ou locaux.
|
||||||
|
|
||||||
|
## Statuts
|
||||||
|
|
||||||
|
| Statut enregistré | Retour WAPT | Situation |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `OK` | `OK` | Export, analyse et enregistrement terminés, même avec des GPO non appliquées ou des listes vides. |
|
||||||
|
| `ERROR` | `ERROR` | Exception capturée : commande en échec, rapport absent, XML invalide, section `ComputerResults` absente, etc. |
|
||||||
|
|
||||||
|
En cas d'erreur, la même clé reçoit uniquement `status: ERROR` et `message`. Les listes et compteurs du précédent succès ne sont pas recopiés. Consulter `status` avant d'exploiter le résultat. Aucun statut `WARNING` n'est utilisé.
|
||||||
|
|
||||||
|
## Déploiement et dépannage
|
||||||
|
|
||||||
|
1. Mettre à jour `setup.py` dans les sources du paquet existant.
|
||||||
|
2. Adapter si nécessaire la description de `WAPT/control` pour mentionner les groupes de sécurité, en conservant l'identité et les autres métadonnées du paquet ; incrémenter sa version selon les conventions du dépôt.
|
||||||
|
3. Reconstruire, signer, téléverser et déployer le paquet, puis lancer l'audit depuis WAPT.
|
||||||
|
4. Consulter `audit-gpresult.computer-gpo` et le journal, qui indique les compteurs de GPO et de groupes de domaine ou l'erreur rencontrée.
|
||||||
|
|
||||||
|
La fréquence des audits dépend de la configuration WAPT ; le script ne crée pas de planification. En cas d'échec, vérifier les droits de l'agent, les données RSoP, l'accès à GPResult et au répertoire temporaire.
|
||||||
|
|
||||||
|
Le rapport utilise le nom fixe `wapt-gpresult-computer.xml` dans `tempfile.gettempdir()`. Éviter les audits simultanés partageant ce répertoire. Un échec de nettoyage est ignoré et peut laisser le fichier sur disque.
|
||||||
|
|
||||||
|
## Contenu du dépôt
|
||||||
|
|
||||||
|
- `setup.py` : collecte et analyse des GPO et groupes de sécurité machine.
|
||||||
|
- `README.md` : fonctionnement, schéma de données et exploitation.
|
||||||
|
- `WAPT/description.txt` : description fournie pour le contrôle existant ; elle décrit les GPO et ne mentionne pas encore les groupes de sécurité. Ce fichier ne remplace pas un `WAPT/control` complet.
|
||||||
Reference in new issue
Block a user