Collecte des LOG NetScaler dans Elasticsearch et visualisation de ceux-ci dans Grafana

Imprimable, PDF & Email

Aujourd’hui, nous avons un menu assez intéressant, et si vous êtes en charge d’un NetScaler dans votre infrastructure, dans cet article, nous allons voir comment nous pouvons collecter leurs journaux pour les traiter plus tard et enfin créer un tableau de bord dans Grafana qui s’affiche en temps réel (ou historique) Les données collectées.

 

Alors ce que j’ai dit, nous pouvons faire en sorte que notre Citrix NetScaler envoie ses journaux à Logstash pour qu’ils soient traités et séparés en données structurées, c’est-à-dire des lignes de différents journaux. Nous stockerons ces informations dans un index Elasticsearch, puis avec un connecteur ou une « source de données »’ de Grafana, nous pourrons accéder à ces données, pour les visualiser en temps réel ou dans un certain laps de temps (Dernières 24h, mois…). Et chacun peut faire le tableau de bord en fonction du rôle joué par son NS, si le service de passerelle voit les adresses IP publiques qui accèdent, Trafics… Si nous avons un Content Switching idem en plus des destinations… Si nous avons un équilibrage de charge, alors analysez vraiment où vont les connexions…  en fin de compte, tout ce qui est stocké dans un journal peut être exploité et NetScaler est un appareil très intéressant pour savoir ce qui se passe à l’intérieur, comme l’affichage des authentifications, correct ou incorrect.

 

Tout d’abord, nous devons évidemment faire installer la partie Elastic Stack, Ce qui a été Logstash, Recherche élastique et Kibana; il s’agirait alors d’indiquer à notre NetScaler d’envoyer les journaux à Logstash, vers le port de notre choix, Nous allons en inventer un (depuis “Système” > “Audit” > “Audit Syslog”. N’oubliez pas d’enregistrer la configuration dans le NetScaler.

 

La prochaine chose à faire sera de créer un fichier dans Logstash que vous devrez ingérer, Transformer et envoyer des données. Primero escuchar en el puerto UDP indicado en el paso anterior; deuxième, tratar los logs que recibe y separarlos en distintos campos para ser por último almacenados en nuestro Elasticsearch.

 

Entrée {
        UDP {
                type => "Netscaler"
                port => "1517"
                Mots-clés => ["Netscaler"]
        }
}

filtre {

        si [type] == "Netscaler" {
                        Grok {
                            match => { "Message" => [
                              "^<%{POSINT:syslog_pri}>%{ESPACE}%{DATE_US:Log_fecha}:%{HEURE:Log_hora}%{ESPACE}%{SYSLOGHOST:NSlog_hostname}%{ESPACE}0-EPI-0%{ESPACE}:%{ESPACE}par défaut%{ESPACE}%{MOT:Log_tipo}%{ESPACE}%{MOT:Log_evento}%{ESPACE}%{INT:Log_id}%{ESPACE}0%{ESPACE}:%{ESPACE}Contexte%{ESPACE}%{NOM D’UTILISATEUR:Utilisateur}@%{IPV4:IP_origen}%{ESPACE}-%{ESPACE}SessionId:%{ESPACE}%{INT:Session_id}%{ESPACE}-%{ESPACE}Utilisateur%{ESPACE}%{NOM D’UTILISATEUR:Usuario2}%{ESPACE}-%{ESPACE}Client_ip %{ESPACE}%{IPV4:IP_origen2}%{ESPACE}-%{ESPACE}Nat_ip %{ESPACE}\"IP mappée"%{ESPACE}-%{ESPACE}Vserver%{ESPACE}%{IPV4:vServer_ip}:%{NOMBRE:vServer_puerto}%{ESPACE}-%{ESPACE}Start_time %{ESPACE}\"%{DATE_US:Inicio_fecha}:%{HEURE:Inicio_hora}%{ESPACE}\"%{ESPACE}-%{ESPACE}End_time %{ESPACE}\"%{DATE_US:Fin_fecha}:%{HEURE:Fin_hora}%{ESPACE}\"%{ESPACE}-%{ESPACE}Durée%{ESPACE}%{HEURE:Duración}%{ESPACE}-%{ESPACE}Http_resources_accessed %{ESPACE}%{NOMBRE:Http_resources_accessed}%{ESPACE}-%{ESPACE}NonHttp_services_accessed %{ESPACE}%{NOMBRE:NonHttp_services_accessed}%{ESPACE}-%{ESPACE}Total_TCP_connections %{ESPACE}%{NOMBRE:Total_TCP_connections}%{ESPACE}-%{ESPACE}Total_UDP_flows %{ESPACE}%{NOMBRE:otal_UDP_flows}%{ESPACE}-%{ESPACE}Total_policies_allowed %{ESPACE}%{NOMBRE:Total_policies_allowed}%{ESPACE}-%{ESPACE}Total_policies_denied %{ESPACE}%{NOMBRE:Total_policies_denied}%{ESPACE}-%{ESPACE}Total_bytes_send %{ESPACE}%{NOMBRE:Total_bytes_send}%{ESPACE}-%{ESPACE}Total_bytes_recv %{ESPACE}%{NOMBRE:Total_bytes_recv}%{ESPACE}-%{ESPACE}Total_compressedbytes_send %{ESPACE}%{NOMBRE:Total_compressedbytes_send}%{ESPACE}-%{ESPACE}Total_compressedbytes_recv %{ESPACE}%{NOMBRE:Total_compressedbytes_recv}%{ESPACE}-%{ESPACE}Compression_ratio_send %{ESPACE}%{NOMBRE:Compression_ratio_send}\%%{ESPACE}-%{ESPACE}Compression_ratio_recv %{ESPACE}%{NOMBRE:Compression_ratio_recv}\%%{ESPACE}-%{ESPACE}Méthode de déconnexion%{ESPACE}\"%{DATE:LogoutMethod}\"%{ESPACE}-%{ESPACE}Groupe(s)%{ESPACE}\"%{DATE:Group}\"",
                              "^<%{POSINT:syslog_pri}>%{ESPACE}%{DATE_US:Log_fecha}:%{HEURE:Log_hora}%{ESPACE}%{SYSLOGHOST:NSlog_hostname}%{ESPACE}0-EPI-0%{ESPACE}:%{ESPACE}par défaut%{ESPACE}%{MOT:Log_tipo}%{ESPACE}%{MOT:Log_evento}%{ESPACE}%{INT:Log_id}%{ESPACE}0%{ESPACE}:%{ESPACE}Contexte%{ESPACE}%{NOM D’UTILISATEUR:Utilisateur}@%{IPV4:IP_origen}%{ESPACE}-%{ESPACE}SessionId:%{ESPACE}%{INT:Session_id}%{ESPACE}-%{ESPACE}Utilisateur%{ESPACE}%{NOM D’UTILISATEUR:Usuario2}%{ESPACE}-%{ESPACE}Client_ip %{ESPACE}%{IPV4:IP_origen2}%{ESPACE}-%{ESPACE}Nat_ip %{ESPACE}\"IP mappée"%{ESPACE}-%{ESPACE}Vserver%{ESPACE}%{IPV4:vServer_ip}:%{NOMBRE:vServer_puerto}%{ESPACE}-%{ESPACE}%{GREEDYDATA:Message}",
                              "^<%{POSINT:syslog_pri}>%{ESPACE}%{DATE_US:Log_fecha}:%{HEURE:Log_hora}%{ESPACE}%{SYSLOGHOST:NSlog_hostname}%{ESPACE}0-EPI-0%{ESPACE}:%{ESPACE}par défaut%{ESPACE}%{MOT:Log_tipo}%{ESPACE}%{MOT:Log_evento}%{ESPACE}%{INT:Log_id}%{ESPACE}0%{ESPACE}:%{ESPACE}Utilisateur%{ESPACE}%{NOM D’UTILISATEUR:Utilisateur}%{ESPACE}-%{ESPACE}Client_ip %{ESPACE}%{IPV4:IP_origen}%{ESPACE}-%{ESPACE}%{GREEDYDATA:Message}",
                              "^<%{POSINT:syslog_pri}>%{ESPACE}%{DATE_US:Log_fecha}:%{HEURE:Log_hora}%{ESPACE}%{SYSLOGHOST:NSlog_hostname}%{ESPACE}0-EPI-0%{ESPACE}:%{ESPACE}par défaut%{ESPACE}%{MOT:Log_tipo}%{ESPACE}%{MOT:Log_evento}%{ESPACE}%{INT:Log_id}%{ESPACE}0%{ESPACE}:%{ESPACE}Source%{ESPACE}%{IPV4:IP_origen}:%{NOMBRE:Puerto_origen}%{ESPACE}-%{ESPACE}Vserver%{ESPACE}%{IPV4:vServer_ip}:%{NOMBRE:vServer_puerto}%{ESPACE}-%{ESPACE}NatIP%{ESPACE}%{IPV4:NAT_ip}:%{NOMBRE:NAT_puerto}%{ESPACE}-%{ESPACE}Destination%{ESPACE}%{IPV4:IP_destino}:%{NOMBRE:Puerto_destino}%{ESPACE}-%{ESPACE}Delink%{ESPACE}Time%{ESPACE}%{DATE_US:Delink_fecha}:%{HEURE:Delink_hora}%{ESPACE}-%{ESPACE}Total_bytes_send %{ESPACE}%{INT:Total_bytes_enviados}%{ESPACE}-%{ESPACE}Total_bytes_recv %{ESPACE}%{INT:Total_bytes_recibidos}",
                              "^<%{POSINT:syslog_pri}>%{ESPACE}%{DATE_US:Log_fecha}:%{HEURE:Log_hora}%{ESPACE}%{SYSLOGHOST:NSlog_hostname}%{ESPACE}0-EPI-0%{ESPACE}:%{ESPACE}par défaut%{ESPACE}%{MOT:Log_tipo}%{ESPACE}%{MOT:Log_evento}%{ESPACE}%{INT:Log_id}%{ESPACE}0%{ESPACE}:%{ESPACE}Source%{ESPACE}%{IPV4:IP_origen}:%{NOMBRE:Puerto_origen}%{ESPACE}-%{ESPACE}Destination%{ESPACE}%{IPV4:Destino_ip}:%{NOMBRE:Destino_puerto}%{ESPACE}-%{ESPACE}Start%{ESPACE}Time%{ESPACE}%{DATE_US:Inicio_fecha}:%{HEURE:Inicio_hora}%{ESPACE}-%{ESPACE}End%{ESPACE}Time%{ESPACE}%{DATE_US:Fin_fecha}:%{HEURE:Fin_hora}%{ESPACE}-%{ESPACE}Total_bytes_send %{ESPACE}%{INT:Total_bytes_enviados}%{ESPACE}-%{ESPACE}Total_bytes_recv %{ESPACE}%{INT:Total_bytes_recibidos}",
                              "^<%{POSINT:syslog_pri}>%{ESPACE}%{DATE_US:Log_fecha}:%{HEURE:Log_hora}%{ESPACE}%{SYSLOGHOST:NSlog_hostname}%{ESPACE}0-EPI-0%{ESPACE}:%{ESPACE}par défaut%{ESPACE}%{MOT:Log_tipo}%{ESPACE}%{MOT:Log_evento}%{ESPACE}%{INT:Log_id}%{ESPACE}0%{ESPACE}:%{ESPACE}Source%{ESPACE}%{IPV4:IP_origen}:%{NOMBRE:Puerto_origen}%{ESPACE}-%{ESPACE}Vserver%{ESPACE}%{IPV4:vServer_ip}:%{NOMBRE:vServer_puerto}%{ESPACE}-%{ESPACE}NatIP%{ESPACE}%{IPV4:NAT_ip}:%{NOMBRE:NAT_puerto}%{ESPACE}-%{ESPACE}Destination%{ESPACE}%{IPV4:IP_destino}:%{NOMBRE:Puerto_destino}%{ESPACE}-%{ESPACE}Delink%{ESPACE}Time%{ESPACE}%{DATE_US:Delink_fecha}:%{HEURE:Delink_hora}%{ESPACE}Total_bytes_send %{ESPACE}%{INT:Total_bytes_enviados}%{ESPACE}-%{ESPACE}Total_bytes_recv %{ESPACE}%{INT:Total_bytes_recibidos}",
                              "^<%{POSINT:syslog_pri}>%{ESPACE}%{DATE_US:Log_fecha}:%{HEURE:Log_hora}%{ESPACE}%{SYSLOGHOST:NSlog_hostname}%{ESPACE}0-EPI-0%{ESPACE}:%{ESPACE}par défaut%{ESPACE}%{MOT:Log_tipo}%{ESPACE}%{MOT:Log_evento}%{ESPACE}%{INT:Log_id}%{ESPACE}0%{ESPACE}:%{ESPACE}SPCBId%{ESPACE}%{INT:SPCBId}%{ESPACE}-%{ESPACE}ClientIP%{ESPACE}%{IPV4:IP_origen}%{ESPACE}-%{ESPACE}ClientPort%{ESPACE}%{NOMBRE:Puerto_origen}%{ESPACE}-%{ESPACE}VserverServiceIP%{ESPACE}%{IPV4:vServer_ip}%{ESPACE}-%{ESPACE}VserverServicePort%{ESPACE}%{NOMBRE:vServer_puerto}%{ESPACE}-%{ESPACE}ClientVersion%{ESPACE}%{DATE:Client_version}%{ESPACE}-%{ESPACE}CipherSuite%{ESPACE}\"%{DATE:Cipher_suite}\"(%{ESPACE}-%{ESPACE}Session%{ESPACE}Reuse%{ESPACE}-%{ESPACE}HandshakeTime%{ESPACE}%{INT:Handshake_time}%{ESPACE}ms)?",
                              "^<%{POSINT:syslog_pri}>%{ESPACE}%{DATE_US:Log_fecha}:%{HEURE:Log_hora}%{ESPACE}%{SYSLOGHOST:NSlog_hostname}%{ESPACE}0-EPI-0%{ESPACE}:%{ESPACE}par défaut%{ESPACE}%{MOT:Log_tipo}%{ESPACE}%{MOT:Log_evento}%{ESPACE}%{INT:Log_id}%{ESPACE}0%{ESPACE}:%{ESPACE}SPCBId%{ESPACE}%{INT:SPCBId}%{ESPACE}-%{ESPACE}IssuerName%{ESPACE}\"%{ESPACE}%{DATE:Issuer_name}\"",
                              "^<%{POSINT:syslog_pri}>%{ESPACE}%{DATE_US:Log_fecha}:%{HEURE:Log_hora}%{ESPACE}%{SYSLOGHOST:NSlog_hostname}%{ESPACE}0-EPI-0%{ESPACE}:%{ESPACE}par défaut%{ESPACE}%{MOT:Log_tipo}%{ESPACE}%{MOT:Log_evento}%{ESPACE}%{INT:Log_id}%{ESPACE}0%{ESPACE}:%{ESPACE}SPCBId%{ESPACE}%{INT:SPCBId}%{ESPACE}-%{ESPACE}SubjectName%{ESPACE}\"%{ESPACE}%{DATE:Subject_name}\"",
                              "^<%{POSINT:syslog_pri}>%{ESPACE}%{DATE_US:Log_fecha}:%{HEURE:Log_hora}%{ESPACE}%{SYSLOGHOST:NSlog_hostname}%{ESPACE}0-EPI-0%{ESPACE}:%{ESPACE}par défaut%{ESPACE}%{MOT:Log_tipo}%{ESPACE}%{MOT:Log_evento}%{ESPACE}%{INT:Log_id}%{ESPACE}0%{ESPACE}:%{ESPACE}Contexte%{ESPACE}%{NOM D’UTILISATEUR:Utilisateur}@%{IPV4:IP_origen}%{ESPACE}-%{ESPACE}SessionId:%{ESPACE}%{INT:Session_id}%{ESPACE}-%{ESPACE}%{NOM D’HÔTE:FQDN}%{ESPACE}Utilisateur%{ESPACE}%{NOM D’UTILISATEUR:Usuario2}%{ESPACE}:%{ESPACE}Groupe(s)%{ESPACE}%{DATE:Groupe}%{ESPACE}:%{ESPACE}Vserver%{ESPACE}%{IPV4:vServer_ip}:%{NOMBRE:vServer_puerto}%{ESPACE}-%{ESPACE}%{DATE_US:Date}:%{HEURE:Heure}%{ESPACE}:%{ESPACE}%{GREEDYDATA:Message}",
                              "^<%{POSINT:syslog_pri}>%{ESPACE}%{DATE_US:Log_fecha}:%{HEURE:Log_hora}%{ESPACE}%{SYSLOGHOST:NSlog_hostname}%{ESPACE}0-EPI-0%{ESPACE}:%{ESPACE}par défaut%{ESPACE}%{MOT:Log_tipo}%{ESPACE}%{MOT:Log_evento}%{ESPACE}%{INT:Log_id}%{ESPACE}0%{ESPACE}:%{ESPACE}%{GREEDYDATA:Message}"
                                       ]
                            }
                        }

                        GéoIP {
                          la source => "IP_origen"
                          cible => "GéoIP"
                          add_field => [ "[GéoIP][Coordonnées]", "%{[GéoIP][Longitude]}" ]
                          add_field => [ "[GéoIP][Coordonnées]", "%{[GéoIP][Latitude]}"  ]
                        }

                        Muet {
                          convertir => [ "[GéoIP][Coordonnées]", "flotter" ]
                          convertir => [ "Total_bytes_enviados", "Entier" ]
                          convertir => [ "Total_bytes_recibidos", "Entier" ]
                        }
        }
}

sortie {

        si ([type]=="Netscaler"){

                Recherche élastique {
                   indice => "Netscaler-%{+AAAA. MM.jj}"
                   hôtes=> "DIRECCION_IP_ELASTICSEARCH:9200"
                }

        }
}

Créons donc par exemple le fichier de configuration suivant '/etc/logstash/conf.d/netscaler.conf', Je vous laisse mon exemple ci-dessous. Mes filtres sont très basiques et d’abord de Logstash, Mais ils fonctionnent 😉, donc si vous êtes intéressé, vous pouvez les copier, et si vous les améliorez, vous me les passez 🙂 À la fin, nous indiquerons dans la sortie le serveur Elasticsearch où envoyer les données et l’index où elles seront stockées; N’oubliez pas que si vous avez l’authentification, mettez les paramètres 'username'’ & 'mot de passe’ dans la sortie. La vérité est que je regarde le code maintenant et qu’il peut être amélioré, Je me suis gratté avec les espaces dont je me souviens… J’espère que vous pouvez me pardonner mais ça marche, du moins avec les dernières versions telles que NetScaler 13.0.

 

Une fois le fichier de configuration créé, n’oubliez pas de redémarrer le service Logstash pour recharger. Après comme toujours, nous irons à Kibana et une fois que les données arriveront, nous pourrons aller à “Gestion” > “Gestion de la pile” > “Kibana” > “Modèles d’indices” > “Créer un modèle d’index” Pour créer le modèle d’index, Comme je l’ai dit, comme d'habitude (dans ce cas et sans les guillemets) 'netscaler-*’ et nous aurons les données déjà stockées correctement dans Elasticsearch. Maintenant, nous pouvions nous connecter à partir de “Découvrir” à notre index NetScaler et visualiser qu’il collecte des données.

 

Et puis, après la création de l’index dans Kibana, maintenant, dans notre Grafana, nous devrions créer un “Source des données” qui cible notre Elasticsearch et l’index NetScaler. Ensuite, il s’agit de laisser libre cours à votre imagination, créer un tableau de bord avec différents tableaux de bord, avec différentes données à visualiser, Un Carte du monde avec connexions entrantes, Une question de style Sankey pour afficher les adresses IP d’origine/de destination et le trafic envoyé, au format colonne, dans pat pour afficher des données spécifiques, par exemple les identifiants corrects, Incorrect, Les connexions…

Tout peut être utilisé pour que vous preniez des idées et les amélioriez, Avec cela, vous pourrez voir ce qui se passe dans notre(s) Citrix NetScaler en temps réel, Mettre un rafraîchissement automatique tous les 10 secondes est très impressionnant, Cela nous aidera également à analyser le résumé d’une journée, ou savoir quand quelque chose d’étrange se produit… Comme d'habitude, Merci à tous et encore à ceux qui déplacent ce type de contenu sur les réseaux sociaux 😉

 

Articles recommandés

Auteur

nheobug@bujarra.com
Autor del blog Bujarra.com Cualquier necesidad que tengas, N’hésitez pas à me contacter, J’essaierai de vous aider chaque fois que je le pourrai, Partager, c’est vivre ;) . Profiter des documents!!!