Skip to main content

NXLog : configuration sur un contrôleur de domaine

Contexte

Un contrôleur de domaine (DC) est la machine la plus critique d’un SI Windows. C’est là que transitent toutes les authentifications, les modifications de comptes et les requêtes Kerberos.

La configuration NXLog d’un DC est donc plus complète que celle d’un serveur membre : on collecte les journaux System, Application, Setup, Security, et on ajoute les channels spécifiques à Active Directory (Directory Service, DNS Server, etc.).

Note : la stratégie d’audit doit être configurée au préalable via GPO. Voir l’article “Audit des événements Windows”.

Configuration complète

Panic Soft

define ROOT     C:\Program Files (x86)\nxlog
define LOGDIR   %ROOT%\data
define LOGFILE  %LOGDIR%\nxlog.log

LogFile   %LOGFILE%
Moduledir %ROOT%\modules
CacheDir  %ROOT%\data
Pidfile   %ROOT%\data\nxlog.pid
SpoolDir  %ROOT%\data

<Extension _gelf>
    Module xm_gelf
</Extension>

<Input in_system>
    Module im_msvistalog
    Query <QueryList>\
      <Query Id="0">\
        <Select Path="System">*</Select>\
      </Query>\
    </QueryList>
    ReadFromLast TRUE
    SavePos TRUE
</Input>

<Input in_application>
    Module im_msvistalog
    Query <QueryList>\
      <Query Id="0">\
        <Select Path="Application">*</Select>\
      </Query>\
    </QueryList>
    ReadFromLast TRUE
    SavePos TRUE
</Input>

<Input in_setup>
    Module im_msvistalog
    Query <QueryList>\
      <Query Id="0">\
        <Select Path="Setup">*</Select>\
      </Query>\
    </QueryList>
    ReadFromLast TRUE
    SavePos TRUE
</Input>

<Input in_security>
    Module im_msvistalog
    Query <QueryList>\
      <Query Id="0">\
        <Select Path="Security">*</Select>\
      </Query>\
    </QueryList>

    Exec if not defined($EventID) drop();

    # Filtrage Security pour un DC
    # Authentification
    Exec $keep = ( \
        $EventID == 4624 or $EventID == 4625 or $EventID == 4648 or $EventID == 4672 or \
        # Gestion des comptes et groupes
        $EventID == 4720 or $EventID == 4722 or $EventID == 4723 or $EventID == 4724 or $EventID == 4725 or $EventID == 4726 or $EventID == 4738 or \
        $EventID == 4728 or $EventID == 4729 or $EventID == 4732 or $EventID == 4733 or $EventID == 4756 or $EventID == 4757 or \
        $EventID == 4740 or $EventID == 4767 or \
        # Kerberos
        $EventID == 4768 or $EventID == 4769 or $EventID == 4771 or $EventID == 4776 or \
        # Processus et services
        $EventID == 4688 or $EventID == 4697 or \
        # Taches planifiees
        $EventID == 4698 or $EventID == 4699 or $EventID == 4700 or $EventID == 4701 or $EventID == 4702 or \
        # Strategie d'audit, effacement de logs, heure systeme
        $EventID == 4719 or $EventID == 1102 or $EventID == 4616 or \
        # GPO
        $EventID == 4739 or \
        # Modifications AD (Directory Service Changes)
        $EventID == 5136 or $EventID == 5137 or $EventID == 5138 or $EventID == 5139 or $EventID == 5141 \
    );

    Exec if $keep != TRUE drop();

    ReadFromLast TRUE
    SavePos TRUE
</Input>

<Input in_directory_service>
    Module im_msvistalog
    Query <QueryList>\
      <Query Id="0">\
        <Select Path="Directory Service">*</Select>\
      </Query>\
    </QueryList>
    ReadFromLast TRUE
    SavePos TRUE
</Input>

<Input in_dns>
    Module im_msvistalog
    Query <QueryList>\
      <Query Id="0">\
        <Select Path="DNS Server">*</Select>\
      </Query>\
    </QueryList>
    ReadFromLast TRUE
    SavePos TRUE
</Input>

<Output out_gelf>
    Module      om_tcp
    Host        graylog_server
    Port        12201
    OutputType  GELF_TCP

    Exec $gl_role = "dc01";
    Exec $gl_env  = "prod";
</Output>

<Route r_dc>
    Path in_system, in_application, in_setup, in_security, in_directory_service, in_dns => out_gelf
</Route>

Explication des choix

Filtrage Security

Le journal Security sur un DC est extrêmement verbeux. Sans filtrage, on peut générer des milliers d’événements par minute sur un domaine actif. La liste d’EventID ci-dessus couvre :

  • Les ouvertures de session et échecs (brute force, mouvements latéraux)
  • Les modifications de comptes et groupes (élévation de privilèges)
  • Les requêtes Kerberos (Kerberoasting, AS-REP Roasting)
  • Les tâches planifiées (persistance)
  • Les modifications d’audit et effacements de logs (anti-forensic)
  • Les modifications AD (5136-5141) : ajout d’attributs, déplacement d’objets, etc.

Channels supplémentaires

  • Directory Service : réplication AD, erreurs LDAP, problèmes de base NTDS
  • DNS Server : requêtes DNS suspectes, tunneling DNS, erreurs de zone

Champs de normalisation

Les champs source, EventID et Channel sont déjà fournis par GELF et im_msvistalog, inutile de les redéfinir. Les champs personnalisés $gl_role et $gl_env permettent de filtrer dans Graylog par rôle et environnement. C’est indispensable quand on a plusieurs serveurs qui envoient vers le même Graylog.

Vérification

Après déploiement :

PS> Restart-Service nxlog
PS> Get-Content "C:\Program Files (x86)\nxlog\data\nxlog.log" -Tail 20

Si le service démarre sans erreur, vérifier côté Graylog que les messages arrivent bien sur l’input GELF TCP (port 12201).

Erreurs fréquentes

  • Le service ne démarre pas : vérifier la syntaxe du nxlog.conf. Un or manquant dans la liste des EventID ou un backslash oublié en fin de ligne sont les causes les plus courantes.
  • Pas de messages dans Graylog : vérifier que le port 12201/TCP est ouvert dans le pare-feu Windows et côté réseau.
  • Messages sans EventID : certains événements n’ont pas de champ EventID. La ligne Exec if not defined($EventID) drop(); les élimine.