Recopilant els LOGs de NetScaler a Elasticsearch i visualitzant-los a Grafana

Avui hem un menú bastant interessant, i si és que si tens a la teva càrrega alguna NetScaler en la teva infraestructura, en aquest post veremos com podem recopilar els seus logs per després ser tractats i finalment farnos un dashboard en Grafana que mostre en temps real (o històric) les dades recopilades.

 

Així que el que s' ha dit, podem fer que el nostre Citrix NetScaler enviï els seus logs a Logstash per a que els tractes i separen en dades estructurades el que són línies de distintos logs. Emmagatzemarem en un índex d'Elasticsearch aquesta informació i després amb un connector o 'Data Source’ de Grafana podremos accedir a aquests dades, per visualitzarlos en temps real o en un període de temps determinat (últimas 24h, mes…). Y cada uno puede hacerse el dashboard en base al rol que haga su NS, si té el servei Gateway viendo les públiques de la IP que acceden, trànsits… Si tenim un Content Switching ídem a més de destinacions… Si tenim un Load Balancing pues analitzar realment per on van les connexions…  al final tot el que s'emmagatzema en un log lo podem explotar i NetScaler és un dispositiu molt interessant per conèixer què passa dentro, com poden ser la visualització de les autenticacions, correctes o incorrectes.

 

Primer òbviament hem de tenir la part d'Elastic Stack instal·lada, el que ve sent Logstash, Elasticsearch y Kibana; després ja seria indicarle al nostre NetScaler que envia els Logs a Logstash, al port que ens pugui agradar, ens inventarem un (des de “System” > “Auditing” > “Syslog Auditing”. Recordar grabar la configuración en el NetScaler.

 

Lo siguiente será crear un fichero en Logstash que haurà d'ingestar, transformar i enviar els dades. Primero escuchar en el puerto UDP indicado en el paso anterior; segon, tratar los logs que recibe y separarlos en distintos campos para ser por último almacenados en nuestro Elasticsearch.

 

input {
        udp {
                type => "Netscaler"
                port => "1517"
                tags => ["Netscaler"]
        }
}

filter {

        if [type] == "Netscaler" {
                        grok {
                            match => { "message" => [
                              "^<%{POSINT:syslog_pri}>%{SPACE}%{DATE_US:Log_fecha}:%{TIME:Log_hora}%{SPACE}%{SYSLOGHOST:NSlog_hostname}%{SPACE}0-PPE-0%{SPACE}:%{SPACE}default%{SPACE}%{WORD:Log_tipo}%{SPACE}%{WORD:Log_evento}%{SPACE}%{INT:Log_id}%{SPACE}0%{SPACE}:%{SPACE}Context%{SPACE}%{USERNAME:Usuari}@%{IPV4:IP_origen}%{SPACE}-%{SPACE}SessionId:%{SPACE}%{INT:Session_id}%{SPACE}-%{SPACE}User%{SPACE}%{USERNAME:Usuario2}%{SPACE}-%{SPACE}Client_ip%{SPACE}%{IPV4:IP_origen2}%{SPACE}-%{SPACE}Nat_ip%{SPACE}\"Mapped Ip\"%{SPACE}-%{SPACE}Vserver%{SPACE}%{IPV4:vServer_ip}:%{NUMBER:vServer_puerto}%{SPACE}-%{SPACE}Start_time%{SPACE}\"%{DATE_US:Inicio_fecha}:%{TIME:Inicio_hora}%{SPACE}\"%{SPACE}-%{SPACE}End_time%{SPACE}\"%{DATE_US:Fin_fecha}:%{TIME:Fin_hora}%{SPACE}\"%{SPACE}-%{SPACE}Duration%{SPACE}%{TIME:Durada}%{SPACE}-%{SPACE}Http_resources_accessed%{SPACE}%{NUMBER:Http_resources_accessed}%{SPACE}-%{SPACE}NonHttp_services_accessed%{SPACE}%{NUMBER:NonHttp_services_accessed}%{SPACE}-%{SPACE}Total_TCP_connections%{SPACE}%{NUMBER:Total_TCP_connections}%{SPACE}-%{SPACE}Total_UDP_flows%{SPACE}%{NUMBER:otal_UDP_flows}%{SPACE}-%{SPACE}Total_policies_allowed%{SPACE}%{NUMBER:Total_policies_allowed}%{SPACE}-%{SPACE}Total_policies_denied%{SPACE}%{NUMBER:Total_policies_denied}%{SPACE}-%{SPACE}Total_bytes_send%{SPACE}%{NUMBER:Total_bytes_send}%{SPACE}-%{SPACE}Total_bytes_recv%{SPACE}%{NUMBER:Total_bytes_recv}%{SPACE}-%{SPACE}Total_compressedbytes_send%{SPACE}%{NUMBER:Total_compressedbytes_send}%{SPACE}-%{SPACE}Total_compressedbytes_recv%{SPACE}%{NUMBER:Total_compressedbytes_recv}%{SPACE}-%{SPACE}�_relació_compressió_enviada{SPACE}%{NUMBER:Relació_compressió_enviada}\%%{SPACE}-%{SPACE}�_relació_compressió_rebuda{SPACE}%{NUMBER:Relació_compressió_rebuda}\%%{SPACE}-%{SPACE}%Mètode_tancament_sessió{SPACE}\"%{DADES:Mètode_tancament_sessió}\"%{SPACE}-%{SPACE}Group\(s\)%{SPACE}\"%{DADES:Grup}\"",
                              "^<%{POSINT:syslog_pri}>%{SPACE}%{DATE_US:Log_fecha}:%{TIME:Log_hora}%{SPACE}%{SYSLOGHOST:NSlog_hostname}%{SPACE}0-PPE-0%{SPACE}:%{SPACE}default%{SPACE}%{WORD:Log_tipo}%{SPACE}%{WORD:Log_evento}%{SPACE}%{INT:Log_id}%{SPACE}0%{SPACE}:%{SPACE}Context%{SPACE}%{USERNAME:Usuari}@%{IPV4:IP_origen}%{SPACE}-%{SPACE}SessionId:%{SPACE}%{INT:Session_id}%{SPACE}-%{SPACE}User%{SPACE}%{USERNAME:Usuario2}%{SPACE}-%{SPACE}Client_ip%{SPACE}%{IPV4:IP_origen2}%{SPACE}-%{SPACE}Nat_ip%{SPACE}\"Mapped Ip\"%{SPACE}-%{SPACE}Vserver%{SPACE}%{IPV4:vServer_ip}:%{NUMBER:vServer_puerto}%{SPACE}-%{SPACE}%{GREEDYDATA:Missatge}",
                              "^<%{POSINT:syslog_pri}>%{SPACE}%{DATE_US:Log_fecha}:%{TIME:Log_hora}%{SPACE}%{SYSLOGHOST:NSlog_hostname}%{SPACE}0-PPE-0%{SPACE}:%{SPACE}default%{SPACE}%{WORD:Log_tipo}%{SPACE}%{WORD:Log_evento}%{SPACE}%{INT:Log_id}%{SPACE}0%{SPACE}:%{SPACE}User%{SPACE}%{USERNAME:Usuari}%{SPACE}-%{SPACE}Client_ip%{SPACE}%{IPV4:IP_origen}%{SPACE}-%{SPACE}%{GREEDYDATA:Missatge}",
                              "^<%{POSINT:syslog_pri}>%{SPACE}%{DATE_US:Log_fecha}:%{TIME:Log_hora}%{SPACE}%{SYSLOGHOST:NSlog_hostname}%{SPACE}0-PPE-0%{SPACE}:%{SPACE}default%{SPACE}%{WORD:Log_tipo}%{SPACE}%{WORD:Log_evento}%{SPACE}%{INT:Log_id}%{SPACE}0%{SPACE}:%{SPACE}%Font{SPACE}%{IPV4:IP_origen}:%{NUMBER:Port_origen}%{SPACE}-%{SPACE}Vserver%{SPACE}%{IPV4:vServer_ip}:%{NUMBER:vServer_puerto}%{SPACE}-%{SPACE}%IP_NAT{SPACE}%{IPV4:IP_NAT}:%{NUMBER:Port_NAT}%{SPACE}-%{SPACE}�stinació{SPACE}%{IPV4:IP_destí}:%{NUMBER:Port_destí}%{SPACE}-%{SPACE}�sconnexió{SPACE}%Temps{SPACE}%{DATE_US:Data_desconnexió}:%{TIME:Hora_desconnexió}%{SPACE}-%{SPACE}Total_bytes_send%{SPACE}%{INT:Bytes_totals_enviats}%{SPACE}-%{SPACE}Total_bytes_recv%{SPACE}%{INT:Bytes_totals_rebuts}",
                              "^<%{POSINT:syslog_pri}>%{SPACE}%{DATE_US:Log_fecha}:%{TIME:Log_hora}%{SPACE}%{SYSLOGHOST:NSlog_hostname}%{SPACE}0-PPE-0%{SPACE}:%{SPACE}default%{SPACE}%{WORD:Log_tipo}%{SPACE}%{WORD:Log_evento}%{SPACE}%{INT:Log_id}%{SPACE}0%{SPACE}:%{SPACE}%Font{SPACE}%{IPV4:IP_origen}:%{NUMBER:Port_origen}%{SPACE}-%{SPACE}�stinació{SPACE}%{IPV4:IP_destí}:%{NUMBER:Port_destí}%{SPACE}-%{SPACE}%Inici{SPACE}%Temps{SPACE}%{DATE_US:Inicio_fecha}:%{TIME:Inicio_hora}%{SPACE}-%{SPACE}%Fi{SPACE}%Temps{SPACE}%{DATE_US:Fin_fecha}:%{TIME:Fin_hora}%{SPACE}-%{SPACE}Total_bytes_send%{SPACE}%{INT:Bytes_totals_enviats}%{SPACE}-%{SPACE}Total_bytes_recv%{SPACE}%{INT:Bytes_totals_rebuts}",
                              "^<%{POSINT:syslog_pri}>%{SPACE}%{DATE_US:Log_fecha}:%{TIME:Log_hora}%{SPACE}%{SYSLOGHOST:NSlog_hostname}%{SPACE}0-PPE-0%{SPACE}:%{SPACE}default%{SPACE}%{WORD:Log_tipo}%{SPACE}%{WORD:Log_evento}%{SPACE}%{INT:Log_id}%{SPACE}0%{SPACE}:%{SPACE}%Font{SPACE}%{IPV4:IP_origen}:%{NUMBER:Port_origen}%{SPACE}-%{SPACE}Vserver%{SPACE}%{IPV4:vServer_ip}:%{NUMBER:vServer_puerto}%{SPACE}-%{SPACE}%IP_NAT{SPACE}%{IPV4:IP_NAT}:%{NUMBER:Port_NAT}%{SPACE}-%{SPACE}�stinació{SPACE}%{IPV4:IP_destí}:%{NUMBER:Port_destí}%{SPACE}-%{SPACE}�sconnexió{SPACE}%Temps{SPACE}%{DATE_US:Data_desconnexió}:%{TIME:Hora_desconnexió}%{SPACE}Total_bytes_send%{SPACE}%{INT:Bytes_totals_enviats}%{SPACE}-%{SPACE}Total_bytes_recv%{SPACE}%{INT:Bytes_totals_rebuts}",
                              "^<%{POSINT:syslog_pri}>%{SPACE}%{DATE_US:Log_fecha}:%{TIME:Log_hora}%{SPACE}%{SYSLOGHOST:NSlog_hostname}%{SPACE}0-PPE-0%{SPACE}:%{SPACE}default%{SPACE}%{WORD:Log_tipo}%{SPACE}%{WORD:Log_evento}%{SPACE}%{INT:Log_id}%{SPACE}0%{SPACE}:%{SPACE}%ID_SPCB{SPACE}%{INT:ID_SPCB}%{SPACE}-%{SPACE}%IP_client{SPACE}%{IPV4:IP_origen}%{SPACE}-%{SPACE}Port_client{SPACE}%{NUMBER:Port_origen}%{SPACE}-%{SPACE}%IP_servidor_V{SPACE}%{IPV4:vServer_ip}%{SPACE}-%{SPACE}Port_servidor_V{SPACE}%{NUMBER:vServer_puerto}%{SPACE}-%{SPACE}Versió_client{SPACE}%{DADES:Versió_client}%{SPACE}-%{SPACE}%Conjunt_cifrat{SPACE}\"%{DADES:Conjunt_cifrat}\"(%{SPACE}-%{SPACE}%Sessió{SPACE}%Reutilització{SPACE}-%{SPACE}%Temps_apretada_mans{SPACE}%{INT:Temps_apretada_mans}%{SPACE}ms)?",
                              "^<%{POSINT:syslog_pri}>%{SPACE}%{DATE_US:Log_fecha}:%{TIME:Log_hora}%{SPACE}%{SYSLOGHOST:NSlog_hostname}%{SPACE}0-PPE-0%{SPACE}:%{SPACE}default%{SPACE}%{WORD:Log_tipo}%{SPACE}%{WORD:Log_evento}%{SPACE}%{INT:Log_id}%{SPACE}0%{SPACE}:%{SPACE}%ID_SPCB{SPACE}%{INT:ID_SPCB}%{SPACE}-%{SPACE}%Nom_emissor{SPACE}\"%{SPACE}%{DADES:Nom_emissor}\"",
                              "^<%{POSINT:syslog_pri}>%{SPACE}%{DATE_US:Log_fecha}:%{TIME:Log_hora}%{SPACE}%{SYSLOGHOST:NSlog_hostname}%{SPACE}0-PPE-0%{SPACE}:%{SPACE}default%{SPACE}%{WORD:Log_tipo}%{SPACE}%{WORD:Log_evento}%{SPACE}%{INT:Log_id}%{SPACE}0%{SPACE}:%{SPACE}%ID_SPCB{SPACE}%{INT:ID_SPCB}%{SPACE}-%{SPACE}%Nom_subjecte{SPACE}\"%{SPACE}%{DADES:Nom_subjecte}\"",
                              "^<%{POSINT:syslog_pri}>%{SPACE}%{DATE_US:Log_fecha}:%{TIME:Log_hora}%{SPACE}%{SYSLOGHOST:NSlog_hostname}%{SPACE}0-PPE-0%{SPACE}:%{SPACE}default%{SPACE}%{WORD:Log_tipo}%{SPACE}%{WORD:Log_evento}%{SPACE}%{INT:Log_id}%{SPACE}0%{SPACE}:%{SPACE}Context%{SPACE}%{USERNAME:Usuari}@%{IPV4:IP_origen}%{SPACE}-%{SPACE}SessionId:%{SPACE}%{INT:Session_id}%{SPACE}-%{SPACE}%{HOSTNAME:FQDN}%{SPACE}User%{SPACE}%{USERNAME:Usuario2}%{SPACE}:%{SPACE}Group\(s\)%{SPACE}%{DADES:Grup}%{SPACE}:%{SPACE}Vserver%{SPACE}%{IPV4:vServer_ip}:%{NUMBER:vServer_puerto}%{SPACE}-%{SPACE}%{DATE_US:Data}:%{TIME:Hora}%{SPACE}:%{SPACE}%{GREEDYDATA:Missatge}",
                              "^<%{POSINT:syslog_pri}>%{SPACE}%{DATE_US:Log_fecha}:%{TIME:Log_hora}%{SPACE}%{SYSLOGHOST:NSlog_hostname}%{SPACE}0-PPE-0%{SPACE}:%{SPACE}default%{SPACE}%{WORD:Log_tipo}%{SPACE}%{WORD:Log_evento}%{SPACE}%{INT:Log_id}%{SPACE}0%{SPACE}:%{SPACE}%{GREEDYDATA:Missatge}"
                                       ]
                            }
                        }

                        geoip {
                          font => "IP_origen"
                          destinació => "geoip"
                          afegeix_camp => [ "[geoip][coordenades]", "%{[geoip][longitude]}" ]
                          afegeix_camp => [ "[geoip][coordenades]", "%{[geoip][latitud]}"  ]
                        }

                        modifica {
                          converteix => [ "[geoip][coordenades]", "float" ]
                          converteix => [ "Bytes_totals_enviats", "integer" ]
                          converteix => [ "Bytes_totals_rebuts", "integer" ]
                        }
        }
}

output {

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

                elasticsearch {
                   index => "netscaler-%{+YYYY.MM.dd}"
                   hosts => "DIRECCION_IP_ELASTICSEARCH:9200"
                }

        }
}

Així que creem per exemple el següent fitxer de configuració ‘/etc/logstash/conf.d/netscaler.conf’, jo us deixo el meu exemple aquí a sota. Els meus filtres són molt bàsics i de primer de Logstash, però funcionen 😉 així que si t'interessen els pots copiar, i si els millores me'ls passes 🙂 Al final indicarem a la sortida el servidor d'Elasticsearch on enviar les dades i l'índex on s'emmagatzemarà; recorda que si teniu autenticació posar els paràmetres de 'username'’ & 'password'’ a l'output. La veritat és que estic veient el codi ara i es pot millorar força, em vaig embolicar amb els espais, ho recordo… espero que em pugueu perdonar però funciona, almenys amb les últimes versions com pot ser NetScaler 13.0.

 

Un cop creat el fitxer de configuració, recorda reiniciar el servei de Logstash per recarregar. Després, com sempre, anirem a Kibana i un cop les dades estiguin entrant ja podrem anar a “Management” > “Stack management” > “Kibana” > “Index Patterns” > “Create index pattern” per crear el patró de l'índex, el que s' ha dit, com habitualment (en aquest cas i sense les cometes) 'netscaler-*'’ i tendremos les dades ja en Elasticsearch emmagatzemats de manera correcta. Ara podríamos connectarnos desde “Discover” a nostre índex de NetScaler i visualitzar que està reconeixent datos.

 

Y després ya, tras crear el índex en Kibana, ara en el nostre Grafana hauríem de crear un “Data Source” que apunte contra el nostre Elasticsearch i el índex de NetScaler. Després ja és deixar volar la imaginació, fer un Dashboard amb diferents Panells, amb diferents dades a visualitzar, un mapamundi amb les connexions entrants, uno de estilo Sankey para veure IPs origen/destino y el tráfico que se envían, en format columnas, en taules para veure dades concretes de per exemple los logins correctos, incorrectes, las conexiones…

Todo puede servir para que cojáis ideas y las mejoréis, con esto podréis ver qué pasa en nuestro(s) Citrix NetScaler en tiempo real, posant un refresc automàtic cada 10 segundos queda muy impresionante, també servirà per analitzar el resumen d'una jornada, o conèixer quan alguna cosa extraña succeeix… Com sempre, gràcies a tots i més a els que es mouen aquest tipus de contenidos en xarxes socials 😉

 

Posts recomanats

Autor

nheobug@bujarra.com
Autor del blog Bujarra.com Cualquier necesidad que tengas, no dubtis a contactar amb mi, us intentareu ajudar sempre que pugui, compartir és viure ;) . Gaudir dels documents!!!