Collecte de logs Synology #1 : Configuration du syslog


  1. Introduction
  2. Fonctionnement de collecte chez Synology
  3. Bases de syslog-ng
  4. Applications
  5. Tests
  6. Conclusion
  7. Bibliographie
  8. Annexes

1. Introduction

Bonjour à tous, nous voici dans cette nouvelle série d’articles axée sur la collecte d’événements ainsi que la mise en place de scenarii pour les équipements NAS Synology.

En effet, ces équipements sont de plus en plus utilisés par les petites entreprises comme par les particuliers mais je n’ai pas trouvé de solution satisfaisante à la supervision de ce qu’il se passait sur vos NAS.

J’ai donc décidé de partir de zéro et à la suite de cette série vous serez à même de pouvoir faire pareil et ainsi superviser les création, modification ou encore suppression de fichiers mais également contrôler les connexions à votre serveur VPN hébergé sur votre NAS.

Enfin, pour conclure avant la partie technique voici comment va s’articuler la série :

  1. Comment récupérer les logs sur votre NAS
  2. Comment collecter les logs sur QRadar
  3. Créer des règles de détection

2. Fonctionnement de la collecte chez Synology

Si vous êtes familier à administrer votre NAS Synology vous avez sûrement déjà vu l’application “Centre des journaux” qui permet de visualiser les événements enregistrés sur votre NAS comme les connexions, modifications de fichiers…

Voici un rapide tour d’horizon de l’application :

Sur cette capture on retrouve à gauche le panneau latéral avec les différents menus. Tous ces chiffres que l’on voit sont récupérés via du syslog-ng, en effet, s’il l’on creuse un peu plus en ligne de commandes sur le NAS on trouve les configurations suivantes :

On remarque les fichiers de configurations, avec l’extension *.conf ainsi que les dossiers qui contiennent les configurations pour les différents outils, protocoles… à collecter. Si on revient sur les événements qui sont affichés dans le “Centre de journaux”, on remarque que la volumétrie n’est pas exceptionnelle, que les événements des autres applications ne sont pas remontés, il faut donc trouver un autre moyen d’avoir ce que l’on souhaite.

Pour cela, nous allons directement utiliser syslog-ng et faire notre propre configuration pour envoyer tous nos logs vers un autre outil centralisateur, ici QRadar. Ainsi, nous allons créer un fichier de configuration syslog-ng comme ceci :

# touch /etc/syslog-ng/patterndb.d/qradar.conf

Nous allons voir comment le configurer par la suite.

3. Bases de syslog-ng

Maintenant que votre fichier de configuration est créé, il faut lui rajouter l’en-tête avant de passer à la suite. Pour cela il faut récupérer la version de syslog-ng utilisée comme ceci :

# grep -i 'version' /etc/syslog-ng/syslog-ng.conf

Dans mon cas j’ai la version “3.34” et il faut que je l’ajoute à mon fichier comme ceci :

# grep -i 'version' /etc/syslog-ng/syslog-ng.conf > /etc/syslog-ng/patterndb.d/qradar.conf

Sinon vous pouvez toujours rajouter la ligne contenant la version à la main dans le fichier. Ensuite avant de configurer notre fichier pour aller chercher les logs VPN, d’accès aux fichiers ou encore de connexion, il va falloir voir quelques bases.

a. Requêter un fichier

Dans un premier temps, il faut savoir comment récupérer des logs dans un fichier. Pour ce faire il faut utiliser la fonction “file()” en syslog-ng comme ceci :

source s_1 {
    file("/path/to/log/file");
};

Dans l’exemple ci-dessus nous allons récupérer ce que contient le fichier “/path/to/log/file” et le mettre dans la variable “s_1”. Bien entendu, cette fonction propose plein d’options permettant de changer la fréquence de requête à ce fichier par exemple ou encore la manière de parser le message. Je ne vais pas entrer dans le détail ici mais je vous mets la documentation concernant ce sujet dans les liens.

b. Appliquer un filtre / pattern / template

Maintenant que l’on sait comment récupérer les logs dans un fichier, je vais vous montrer comment appliquer un filtre à ces logs pour ne pas forcément tout garder. À titre d’exemple j’utilise un compte d’administration pour mon serveur Plex qui génère énormément de logs pour toutes les synchronisations et je souhaite donc l’exclure de ma collecte.

Pour appliquer ce choix je vais utiliser la fonction “message()” et ainsi pouvoir filtrer sur la macro MSG (pour plus de détail sur la partie macro, je vous invite à vous pencher sur la documentation via les liens plus bas) comme ceci :

filter f_1 {
    (not message(".*comte_admin.*"))
};

Dans ce filtre, je vais exclure tous les logs qui vont contenir dans leur macro MSG la chaîne de caractère “compte_admin”. Pour conclure sur la partie filtre, il faut savoir que vous pouvez concaténer plusieurs assertions comme en mathématiques et créer des filtres complexes. Si vous souhaitez aller plus loin dans la partie filtre, je vous joins plusieurs liens très intéressants dans la dernière partie.

c. Transfert de logs vers un serveur

Pour terminer sur les bases qu’il va nous falloir pour créer notre configuration, il va falloir trouver comment envoyer tous ces logs vers le serveur QRadar (ou un autre serveur). Il existe dans syslog-ng la possibilité d’envoyer les logs vers un fichier mais également vers un serveur distant en suivant la méthode suivante :

  1. Créer la variable de votre serveur distant, en modifiant l’IP et le port souhaité :
destination qradar_server {
        syslog("IP_ADDRESS" transport("tcp") port(PORT));
};
  1. Transférer les logs :
log {
	source(s_1); filter(f_1); destination(qradar_server);
};

d. Troubleshooting & Tips

Avant de passer à la partie application, je vais vous donner quelques tips pour pouvoir débuguer un éventuel problème.

Premièrement, je vous conseille très fortement d’utiliser l’outil de vérification de configuration comme ceci :

# syslog-ng --syntax-only --cfgfile=/path/to/config/file

Par exemple, si dans ma configuration je fais l’erreur d’oublier un “;” en fin de consigne je vais avoir l’erreur suivante :

Deuxièmement pour ce qui est de la documentation de syslog-ng je vous conseille d’utiliser la fonctionnalité “visualiser en cache” de votre navigateur pour pouvoir accéder aux pages de l’éditeur qui ne sont plus accessibles dorénavant.

4. Applications

Les bases étant acquises, nous allons donc pouvoir appliquer cela à notre NAS pour collecter différentes applications.

a. Logs souhaités

Les NAS Synology peuvent contenir plein de services et il va falloir faire un choix dans les logs. Pour effectuer ce choix, il faut avancer un petit peu dans le processus et se demander quelles sont les scenarii d’attaque que nous souhaitons couvrir. Voici une liste non exhaustive des scenarii accompagnés des logs associés que j’ai choisis :

  1. Authentification malveillante (comprend le bruteforce de compte) :
    • Logs de connexion SSH ;
    • Logs de connexion Web ;
    • Logs de connexion au VPN ;
  2. Extraction de fichier / Modification de fichiers :
    • Logs d’accès aux fichiers ;
  3. Accès au serveur Plex :
    • Logs du serveur Plex.

b. Configuration

Maintenant que nous avons choisi les logs souhaités, il va falloir les récupérer et les filtrer au besoin comme ceci :

  • Logs de connexion SSH / Logs de connexion Web :
source s_auth {
    file("/var/log/auth.log" follow-freq(1) flags(dont-store-legacy-msghdr));
};
log { source(s_auth); rewrite(r_rewrite_audit_log); destination(qradar_server); };
  • Logs de connexion au VPN :
filter f_openvpn { "${.SDATA.journald._TRANSPORT}" eq "stdout" and program("^openvpn");};
log { source(src); filter(f_openvpn); destination(qradar_server); };

Pour les logs VPN, j’utilise une source déjà configuré dans le fichier par défaut de syslog-ng.

  • Logs d’accès aux fichiers :
# files logs parsing
source s_syno_xferlog {
    unix-dgram("/var/run/synologd" owner("system") group("log") perm(0666) log-msg-size(12288));
};

parser p_msg_to_xfer_event {
    csv-parser(columns("IP", "USERNAME", "CMD", "FILESIZE", "FILENAME", "ISDIR", "PERM")
    delimiters("\t")
    flags(escape-none greedy)
    template("${MSG}"));
};

filter f_ftpxfer    { "$PRI" == "1" };
filter f_webfmxfer  { "$PRI" == "2" };
filter f_dsmfmxfer  { "$PRI" == "3" };
filter f_webdavxfer { "$PRI" == "4" };
filter f_smbxfer    { "$PRI" == "5" };
filter f_afpxfer    { "$PRI" == "6" };
filter f_tftpxfer   { "$PRI" == "7" };

# optional files logs
log { source(s_syno_xferlog); filter(f_ftpxfer); parser(p_msg_to_xfer_event); destination(qradar_server); };
log { source(s_syno_xferlog); filter(f_webfmxfer); parser(p_msg_to_xfer_event); destination(qradar_server); };
log { source(s_syno_xferlog); filter(f_dsmfmxfer); parser(p_msg_to_xfer_event); destination(qradar_server); };
log { source(s_syno_xferlog); filter(f_webdavxfer); parser(p_msg_to_xfer_event); destination(qradar_server); };

log { source(s_syno_xferlog); filter(f_smbxfer); parser(p_msg_to_xfer_event); destination(qradar_server); };
log { source(s_syno_xferlog); filter(f_afpxfer); parser(p_msg_to_xfer_event); destination(qradar_server); };
log { source(s_syno_xferlog); filter(f_tftpxfer); parser(p_msg_to_xfer_event); destination(qradar_server); };
  • Logs du serveur Plex :
source s_plex {
    file("/volume1/@apphome/PlexMediaServer/Plex\ Media\ Server/Logs/Plex\ Media\ Server.log" follow-freq(1) flags(no-parse));
};

filter f_plex { (message(".*DEBUG - Request:.*") or message(".*VERBOSE -.*Host.*") or message(".*VERBOSE -.*User-Agent.*") or message(".*VERBOSE -.*Referer.*") or message(".*DEBUG - Auth: authenticated.*")) and not message(".*compte_admin.*") and not message(".*127.0.0.1:32400.*") and not message(".*User-Agent => Lavf.*") };

log { source(s_plex); filter(f_plex); destination(qradar_server_auth); };

5. Tests

Maintenant que nous avons tous nos logs, il ne reste plus qu’à regrouper toutes ces configurations dans un seul fichier en y ajoutant l’en-tête ainsi que le paramétrage de la destination. On obtient donc le fichier que vous retrouverez en Annexes.

Avant de valider que nous avons bien tous les logs, il faut valider que la configuration est correcte.

# syslog-ng --syntax-only --cfgfile=/tmp/qradar.conf

Ensuite nous allons valider la bonne réception et complétude des événements en rajoutant une destination “locale” qui va envoyer les événements sur la NAS. Cela va nous permettre, par le biais d’un tcpdump en local, de valider que tout est bon dans la réception des événements mais aussi dans le contenu.

Dans un premier temps, on active la destination de débug dans le fichier de configuration :

#destination qradar_server { syslog("QRADAR_IP" transport("tcp") port(5141)); };
destination qradar_server { syslog("127.0.0.1" transport("udp") port(5141)); };

Dans un second temps, on ouvre un nouveau terminal sur le NAS et l’on exécute la commande suivante :

# tcpdump -i any dst port 5141 -A

On applique la configuration syslog-ng comme ceci :

# synosystemctl restart syslog-ng

On effectue une action de modification des fichiers via le web sur le NAS et on contrôle dans le terminal avec la capture réseau les logs. Si tout est bien configuré vous aurez les événements suivants :

On voit dans l’exemple ci-dessus, les événements de création de fichier via un upload mais aussi la suppression de ce fichier à la toute fin.

Pour finir, nous allons maintenant tester les logs du serveur VPN, pour cela je relance ma capture réseau et j’effectue une connexion VPN.

La configuration pour la collecte VPN est donc validée. Je vous épargne les vérifications pour le serveur Plex ainsi que pour les connexions à la partie web puisque les vérifications sont faites de la même manière.

Attention, il faut bien penser à remettre la destination comme il se doit, c’est-à-dire commenter la ligne qui permet d’envoyer les événements en local et décommenter la ligne du dessus.

6. Conclusion

Et voilà ! Vous avez les bases de syslog-ng pour pouvoir récupérer les logs que vous souhaitez sur votre NAS Synology. Nous verrons dans un prochain article comment les comprendre correctement dans QRadar.

N’hésitez pas à me faire un retour sur cet article mais aussi à partager vos idées d’outil ou de service qui serait utile de récupérer.

7. Bibliographie

8. Annexes

qradar.conf :

@version: 3.34

### configuration of sourcing

# files logs parsing
source s_syno_xferlog {
    unix-dgram("/var/run/synologd" owner("system") group("log") perm(0666) log-msg-size(12288));
};

# auth logs
source s_auth {
    file("/var/log/auth.log" follow-freq(1) flags(dont-store-legacy-msghdr));
};

# plex logs
source s_plex {
    file("/volume1/@apphome/PlexMediaServer/Plex\ Media\ Server/Logs/Plex\ Media\ Server.log" follow-freq(1) flags(no-parse));
};

### configuration of parsing

# plex logs parsing and filtering
filter f_plex { (message(".*DEBUG - Request:.*") or message(".*VERBOSE -.*Host.*") or message(".*VERBOSE -.*User-Agent.*") or message(".*VERBOSE -.*Referer.*") or message(".*DEBUG - Auth: authenticated.*")) and not message(".*notificatio5.*") and not message(".*127.0.0.1:32400.*") and not message(".*User-Agent => Lavf.*") };

# files logs parsing and filtering
parser p_msg_to_xfer_event {
    csv-parser(columns("IP", "USERNAME", "CMD", "FILESIZE", "FILENAME", "ISDIR", "PERM")
    delimiters("\t")
    flags(escape-none greedy)
    template("${MSG}"));
};

filter f_ftpxfer    { "$PRI" == "1" };
filter f_webfmxfer  { "$PRI" == "2" };
filter f_dsmfmxfer  { "$PRI" == "3" };
filter f_webdavxfer { "$PRI" == "4" };
filter f_smbxfer    { "$PRI" == "5" };
filter f_afpxfer    { "$PRI" == "6" };
filter f_tftpxfer   { "$PRI" == "7" };

# openvpn filtering
filter f_openvpn { "${.SDATA.journald._TRANSPORT}" eq "stdout" and program("^openvpn");};

# audit log rewriting
rewrite r_rewrite_audit_log { subst("\(sshd:session)", "****", value("MESSAGE")); };

### configuration of destination (here qradar)

#destination qradar_server { syslog("QRADAR_IP" transport("tcp") port(5141)); };

destination qradar_server { syslog("127.0.0.1" transport("udp") port(5141)); };

### configuration of sendings

# send authentification logs
log { source(s_auth); rewrite(r_rewrite_audit_log); destination(qradar_server); };

# send openvpn logs
log { source(src); filter(f_openvpn); destination(qradar_server); };

# optional files logs
log { source(s_syno_xferlog); filter(f_ftpxfer); parser(p_msg_to_xfer_event); destination(qradar_server); };
log { source(s_syno_xferlog); filter(f_webfmxfer); parser(p_msg_to_xfer_event); destination(qradar_server); };
log { source(s_syno_xferlog); filter(f_dsmfmxfer); parser(p_msg_to_xfer_event); destination(qradar_server); };
log { source(s_syno_xferlog); filter(f_webdavxfer); parser(p_msg_to_xfer_event); destination(qradar_server); };

# send FileStation and WinFileService logs (creation writing deletion reading modification_of_authorization)
log { source(s_syno_xferlog); filter(f_smbxfer); parser(p_msg_to_xfer_event); destination(qradar_server); };
log { source(s_syno_xferlog); filter(f_afpxfer); parser(p_msg_to_xfer_event); destination(qradar_server); };
log { source(s_syno_xferlog); filter(f_tftpxfer); parser(p_msg_to_xfer_event); destination(qradar_server); };


Merci d’avoir suivi ce petit tuto, en espérant que cela vous ait été utile. N’hésitez pas à me communiquer vos ressentis, tips…etc via le formulaire ci-dessous.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *