Files
Analyse_Reseaux/CREATE_FIREWALL_PARSING.md
2026-05-26 15:10:05 +02:00

8.0 KiB

Guide de Développement : Créer son propre Parseur Firewall

Ce guide explique comment étendre l'outil d'analyse réseau en ajoutant un nouveau parseur pour un modèle de firewall non supporté nativement (ex: CheckPoint, Fortinet, etc.).

Note : Tout au long de ce guide, remplacez MODELE (en majuscule ou minuscule) par le nom de la marque ou du modèle du firewall ciblé.


Étape 1 : Création du script de parsing

Dans le dossier Parseurs_config_Firewall/src/scripts/ (ou script/ selon votre arborescence), créez un nouveau fichier Python nommé json_MODELE.py.

Il est fortement recommandé de s'inspirer des parseurs existants comme json_Forcepoint.py, json_Stormshield.py ou json_PaloAlto.py.

Voici le squelette de code à utiliser (exemple basé sur des logs au format XML) :

#!/usr/bin/env python3
"""
Parser pour configuration MODELE XML vers un format json normalisé OpenConfig YANG
Extrait les groupes d'objets, objets, groupes de services, services, routes, interfaces et règles
"""

import xml.etree.ElementTree as ET
import json
from scripts.export_modele import ParserMixin
from scripts.objets.data import AddressObject, AddressGroup, ServiceObject, ServiceGroup, Interface, SecurityRule, StaticRoute, VirtualRouter
from pathlib import Path

class ModeleParser(ParserMixin):
    """Parser pour fichier Modele"""
    
    def __init__(self, xml_file_path: str):
        """Initialise le parser avec le chemin du fichier"""
        self.xml_file = xml_file_path
        self.tree = None
        self.root = None
        self.config = {
            'address_objects': [],
            'address_groups': [],
            'service_objects': [],
            'service_groups': [],
            'interfaces': [],
            'virtual_routers': [],
            'static_routes': [],
            'security_rules': []
        }
        
    def load_xml(self):
        """Charge le fichier XML"""
        try:
            self.tree = ET.parse(self.xml_file)
            self.root = self.tree.getroot()
            print(f"✓ Fichier XML chargé: {self.xml_file}")
        except ET.ParseError as e:
            print(f"✗ Erreur de parsing XML: {e}")
            raise
        except FileNotFoundError:
            print(f"✗ Fichier non trouvé: {self.xml_file}")
            raise
    
    def _parse_address_objects(self):
        """Parse les objets adresse"""
        address_objects = []
        
        # TODO: Parcourir le XML et instancier des objets AddressObject
        
        self.config['address_objects'] = address_objects
        print(f"✓ Trouvé {len(address_objects)} objets adresse")
    
    def _parse_address_groups(self):
        """Parse les groupes d'adresses"""
        address_groups = []
        
        # TODO: Parcourir le XML et instancier des objets AddressGroup
        
        self.config['address_groups'] = address_groups
        print(f"✓ Trouvé {len(address_groups)} groupes d'adresses")
    
    def _parse_service_objects(self):
        """Parse les objets service"""
        service_objects = []
        
        # TODO: Parcourir le XML et instancier des objets ServiceObject
        
        self.config['service_objects'] = service_objects
        print(f"✓ Trouvé {len(service_objects)} objets service")
    
    def _parse_service_groups(self):
        """Parse les groupes de services"""
        service_groups = []
        
        # TODO: Parcourir le XML et instancier des objets ServiceGroup
        
        self.config['service_groups'] = service_groups
        print(f"✓ Trouvé {len(service_groups)} groupes de services")
    
    def _parse_interfaces(self):
        """Parse les interfaces réseau"""
        interfaces = []
        
        # TODO: Parcourir le XML et instancier des objets Interface
        
        self.config['interfaces'] = interfaces
        print(f"✓ Trouvé {len(interfaces)} interfaces")

    def _parse_virtual_routers(self):
        """Parse les virtual-routers et leurs routes statiques"""
        virtual_routers = []

        # TODO: Parcourir le XML, instancier des VirtualRouter et injecter les StaticRoute

        self.config['virtual_routers'] = virtual_routers
        print(f"✓ Trouvé {len(virtual_routers)} virtual-routers")
    
    def _parse_security_rules(self):
        """Parse les règles de sécurité"""
        security_rules = []

        # TODO: Parcourir le XML et instancier des objets SecurityRule
        
        self.config['security_rules'] = security_rules
        print(f"✓ Trouvé {len(security_rules)} règles de sécurité")
    
    def parse_all(self):
        """Parse tous les éléments de configuration"""
        print("Début du parsing de la configuration MODELE...")
        
        self.load_xml()
        self._parse_address_objects()
        self._parse_address_groups()
        self._parse_service_objects()
        self._parse_service_groups()
        self._parse_interfaces()
        self._parse_virtual_routers()
        self._parse_security_rules()
        
        print("✓ Parsing terminé avec succès!")
    
    def export_to_json(self, output_file: str):
        """Exporte la configuration au format JSON OpenConfig"""
        fw_name = ""
        deviceconfig = self.root.find(".//deviceconfig/system/hostname")
        if deviceconfig is not None and deviceconfig.text:
            fw_name = deviceconfig.text.strip()
            
        openconfig_data = self.to_openconfig_yang("MODELE", [fw_name])
        
        with open(output_file, 'w', encoding='utf-8') as f:
            json.dump(openconfig_data, f, indent=2, ensure_ascii=False)
        
        print(f"✓ Configuration exportée vers: {output_file}")
    
def generate_json_modele(input_file: str, output_file: str):
    """Génère le fichier JSON OpenConfig à partir du fichier XML MODELE"""
    xml_file = Path(input_file)
    if not xml_file.exists():
        print(f"✗ Erreur: Le fichier '{xml_file}' n'existe pas")
        return
    
    try:
        parser = ModeleParser(str(xml_file))
        parser.parse_all()
        parser.print_summary()
        parser.export_to_json(output_file)
        print(f"\n✓ Conversion terminée! Vérifiez le fichier: {output_file}")
    except Exception as e:
        print(f"✗ Erreur: {e}")
        return

if __name__ == "__main__":
    import sys
    if len(sys.argv) != 2:
        print("Usage: python json_MODELE.py <fichier_config.xml>")
        sys.exit(1)
        
    xml_file = sys.argv[1]
    if not Path(xml_file).exists():
        print(f"✗ Erreur: Le fichier '{xml_file}' n'existe pas")
        sys.exit(1)
        
    try:
        parser = ModeleParser(xml_file)
        parser.parse_all()
        parser.print_summary()
        output_file = 'output_Modele.json'
        parser.export_to_json(output_file)
        print(f"\n✓ Conversion terminée! Vérifiez le fichier: {output_file}")
    except Exception as e:
        print(f"✗ Erreur: {e}")
        sys.exit(1)

Étape 2 : Intégration dans le moteur principal (main.py)

Pour que le script global prenne en charge le nouveau modèle, ouvrez le fichier Parseurs_config_Firewall/src/main.py :

  1. Importez votre nouvelle fonction en haut du fichier :
from scripts.json_MODELE import generate_json_modele
  1. Ajoutez la condition correspondante dans le bloc de sélection du type de firewall :
elif firewall_type == "modele":
    generate_json_modele(input_data, output_file_json)
  1. Mettez à jour les instructions textuelles d'usage affichées dans la console si le paramètre saisi est incorrect afin d'inclure "modele" dans la liste des choix valides.

Étape 3 : Adaptation de l'Interface Graphique (GUI)

Afin que le nouveau modèle apparaisse dans l'interface graphique unifiée :

  1. Ouvrez le fichier de gestion de la GUI (gui_firewall.py racine ou script GUI dédié).
  2. Repérez le composant de sélection (Menu déroulant / ComboBox ou liste de boutons radio) listant les firewalls.
  3. Ajoutez MODELE à la liste des choix graphiques.

Important : faire attention si le script prend en compte un dossier ou un fichier.