
Raccolta dei LOG di NetScaler in Elasticsearch e visualizzazione in Grafana
Oggi abbiamo un menu piuttosto interessante, e se sei responsabile di un NetScaler nella tua infrastruttura, in questo post vedremo come possiamo raccogliere i loro log per poi essere elaborati e infine creare una dashboard in Grafana che si mostri in tempo reale (o storico) I dati raccolti.
Quindi quello che ho detto, podemos hacer que nuestro Citrix NetScaler envíe sus logs a Logstash para que los trate y separe en datos estructurados lo que son líneas de distintos logs. Almacenaremos en un índice de Elasticsearch esta información y luego con un conector o ‘Data Source’ de Grafana podremos acceder a estos datos, para visualizarlos en tiempo real o en un periodo de tiempo determinado (últimas 24h, mese…). Y cada uno puede hacerse el dashboard en base al rol que haga su NS, si tiene el servicio Gateway viendo las IP’s públicas que acceden, tráficos… Si tenemos un Content Switching ídem además de destinos… Si tenemos un Load Balancing pues analizar realmente por donde van las conexiones… al final todo lo que se almacena en un log lo podemos explotar y NetScaler es un dispositivo muy interesante para conocer qué pasa dentro, como puedan ser la visualización de las autenticaciones, correctas o incorrectas.
Per prima cosa dobbiamo ovviamente avere installato la parte Elastic Stack, Cosa è stato Registro, Ricerca elastica e Kibana; luego ya sería indicarle a nuestro NetScaler que envíe los Logs a Logstash, al porto di nostra scelta, Ne inventeremo uno (poiché “Sistema” > “Auditing” > “Syslog Auditing”. Recordar grabar la configuración en el NetScaler.
Lo siguiente será crear un fichero en Logstash que deberá de ingestar, Trasforma e invia dati. Primero escuchar en el puerto UDP indicado en el paso anterior; secondo, elaborare i log che riceve e separarli in diversi campi per essere infine memorizzati nel nostro Elasticsearch.
Immissione { UDP { tipo => "Netscaler" porta => "1517" tag => ["Netscaler"] } } filtro { se [digitare] == "Netscaler" { Grok { corrispondenza => { "Messaggio" => [ "^<%{POSINT:syslog_pri}>%{SPACE}%{DATE_US:Log_fecha}:%{TIME:Log_hora}%{SPACE}%{SYSLOGHOST:NSlog_hostname}%{SPACE}0-PPE-0%{SPACE}:%{SPACE}default%{SPACE}%{PAROLA:Log_tipo}%{SPACE}%{PAROLA:Log_evento}%{SPACE}%{INT:Log_id}%{SPACE}0%{SPACE}:%{SPACE}Context%{SPACE}%{NOME UTENTE:Utente}@%{IPV4:IP_origen}%{SPACE}-%{SPACE}SessionId:%{SPACE}%{INT:Session_id}%{SPACE}-%{SPACE}User%{SPACE}%{NOME UTENTE:Usuario2}%{SPACE}-%{SPACE}Client_ip%{SPACE}%{IPV4:IP_origen2}%{SPACE}-%{SPACE}Nat_ip%{SPACE}\"Mapped Ip\"%{SPACE}-%{SPACE}Vserver%{SPACE}%{IPV4:vServer_ip}:%{NUMERO: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:Durata}%{SPACE}-%{SPACE}Http_resources_accessed%{SPACE}%{NUMERO:Http_resources_accessed}%{SPACE}-%{SPACE}NonHttp_services_accessed%{SPACE}%{NUMERO:NonHttp_services_accessed}%{SPACE}-%{SPACE}Total_TCP_connections%{SPACE}%{NUMERO:Total_TCP_connections}%{SPACE}-%{SPACE}Total_UDP_flows%{SPACE}%{NUMERO:otal_UDP_flows}%{SPACE}-%{SPACE}Total_policies_allowed%{SPACE}%{NUMERO:Total_policies_allowed}%{SPACE}-%{SPACE}Total_policies_denied%{SPACE}%{NUMERO:Total_policies_denied}%{SPACE}-%{SPACE}Total_bytes_send%{SPACE}%{NUMERO:Total_bytes_send}%{SPACE}-%{SPACE}Total_bytes_recv%{SPACE}%{NUMERO:Total_bytes_recv}%{SPACE}-%{SPACE}Total_compressedbytes_send%{SPACE}%{NUMERO:Total_compressedbytes_send}%{SPACE}-%{SPACE}Total_compressedbytes_recv%{SPACE}%{NUMERO:Total_compressedbytes_recv}%{SPACE}-%{SPACE}Compression_ratio_send%{SPACE}%{NUMERO:Compression_ratio_send}\%%{SPACE}-%{SPACE}Compression_ratio_recv%{SPACE}%{NUMERO:Compression_ratio_recv}\%%{SPACE}-%{SPACE}LogoutMethod%{SPACE}\"%{DATTERO:LogoutMethod}\"%{SPACE}-%{SPACE}Group\(s\)%{SPACE}\"%{DATTERO:Group}\"", "^<%{POSINT:syslog_pri}>%{SPACE}%{DATE_US:Log_fecha}:%{TIME:Log_hora}%{SPACE}%{SYSLOGHOST:NSlog_hostname}%{SPACE}0-PPE-0%{SPACE}:%{SPACE}default%{SPACE}%{PAROLA:Log_tipo}%{SPACE}%{PAROLA:Log_evento}%{SPACE}%{INT:Log_id}%{SPACE}0%{SPACE}:%{SPACE}Context%{SPACE}%{NOME UTENTE:Utente}@%{IPV4:IP_origen}%{SPACE}-%{SPACE}SessionId:%{SPACE}%{INT:Session_id}%{SPACE}-%{SPACE}User%{SPACE}%{NOME UTENTE:Usuario2}%{SPACE}-%{SPACE}Client_ip%{SPACE}%{IPV4:IP_origen2}%{SPACE}-%{SPACE}Nat_ip%{SPACE}\"Mapped Ip\"%{SPACE}-%{SPACE}Vserver%{SPACE}%{IPV4:vServer_ip}:%{NUMERO:vServer_puerto}%{SPACE}-%{SPACE}%{DATI GREEDYDATA:Messaggio}", "^<%{POSINT:syslog_pri}>%{SPACE}%{DATE_US:Log_fecha}:%{TIME:Log_hora}%{SPACE}%{SYSLOGHOST:NSlog_hostname}%{SPACE}0-PPE-0%{SPACE}:%{SPACE}default%{SPACE}%{PAROLA:Log_tipo}%{SPACE}%{PAROLA:Log_evento}%{SPACE}%{INT:Log_id}%{SPACE}0%{SPACE}:%{SPACE}User%{SPACE}%{NOME UTENTE:Utente}%{SPACE}-%{SPACE}Client_ip%{SPACE}%{IPV4:IP_origen}%{SPACE}-%{SPACE}%{DATI GREEDYDATA:Messaggio}", "^<%{POSINT:syslog_pri}>%{SPACE}%{DATE_US:Log_fecha}:%{TIME:Log_hora}%{SPACE}%{SYSLOGHOST:NSlog_hostname}%{SPACE}0-PPE-0%{SPACE}:%{SPACE}default%{SPACE}%{PAROLA:Log_tipo}%{SPACE}%{PAROLA:Log_evento}%{SPACE}%{INT:Log_id}%{SPACE}0%{SPACE}:%{SPACE}Source%{SPACE}%{IPV4:IP_origen}:%{NUMERO:Puerto_origen}%{SPACE}-%{SPACE}Vserver%{SPACE}%{IPV4:vServer_ip}:%{NUMERO:vServer_puerto}%{SPACE}-%{SPACE}NatIP%{SPACE}%{IPV4:NAT_ip}:%{NUMERO:NAT_puerto}%{SPACE}-%{SPACE}Destination%{SPACE}%{IPV4:IP_destino}:%{NUMERO:Puerto_destino}%{SPACE}-%{SPACE}Delink%{SPACE}Time%{SPACE}%{DATE_US:Delink_fecha}:%{TIME:Delink_hora}%{SPACE}-%{SPACE}Total_bytes_send%{SPACE}%{INT:Total_bytes_enviados}%{SPACE}-%{SPACE}Total_bytes_recv%{SPACE}%{INT:Total_bytes_recibidos}", "^<%{POSINT:syslog_pri}>%{SPACE}%{DATE_US:Log_fecha}:%{TIME:Log_hora}%{SPACE}%{SYSLOGHOST:NSlog_hostname}%{SPACE}0-PPE-0%{SPACE}:%{SPACE}default%{SPACE}%{PAROLA:Log_tipo}%{SPACE}%{PAROLA:Log_evento}%{SPACE}%{INT:Log_id}%{SPACE}0%{SPACE}:%{SPACE}Source%{SPACE}%{IPV4:IP_origen}:%{NUMERO:Puerto_origen}%{SPACE}-%{SPACE}Destination%{SPACE}%{IPV4:Destino_ip}:%{NUMERO:Destino_puerto}%{SPACE}-%{SPACE}Start%{SPACE}Time%{SPACE}%{DATE_US:Inicio_fecha}:%{TIME:Inicio_hora}%{SPACE}-%{SPACE}End%{SPACE}Time%{SPACE}%{DATE_US:Fin_fecha}:%{TIME:Fin_hora}%{SPACE}-%{SPACE}Total_bytes_send%{SPACE}%{INT:Total_bytes_enviados}%{SPACE}-%{SPACE}Total_bytes_recv%{SPACE}%{INT:Total_bytes_recibidos}", "^<%{POSINT:syslog_pri}>%{SPACE}%{DATE_US:Log_fecha}:%{TIME:Log_hora}%{SPACE}%{SYSLOGHOST:NSlog_hostname}%{SPACE}0-PPE-0%{SPACE}:%{SPACE}default%{SPACE}%{PAROLA:Log_tipo}%{SPACE}%{PAROLA:Log_evento}%{SPACE}%{INT:Log_id}%{SPACE}0%{SPACE}:%{SPACE}Source%{SPACE}%{IPV4:IP_origen}:%{NUMERO:Puerto_origen}%{SPACE}-%{SPACE}Vserver%{SPACE}%{IPV4:vServer_ip}:%{NUMERO:vServer_puerto}%{SPACE}-%{SPACE}NatIP%{SPACE}%{IPV4:NAT_ip}:%{NUMERO:NAT_puerto}%{SPACE}-%{SPACE}Destination%{SPACE}%{IPV4:IP_destino}:%{NUMERO:Puerto_destino}%{SPACE}-%{SPACE}Delink%{SPACE}Time%{SPACE}%{DATE_US:Delink_fecha}:%{TIME:Delink_hora}%{SPACE}Total_bytes_send%{SPACE}%{INT:Total_bytes_enviados}%{SPACE}-%{SPACE}Total_bytes_recv%{SPACE}%{INT:Total_bytes_recibidos}", "^<%{POSINT:syslog_pri}>%{SPACE}%{DATE_US:Log_fecha}:%{TIME:Log_hora}%{SPACE}%{SYSLOGHOST:NSlog_hostname}%{SPACE}0-PPE-0%{SPACE}:%{SPACE}default%{SPACE}%{PAROLA:Log_tipo}%{SPACE}%{PAROLA:Log_evento}%{SPACE}%{INT:Log_id}%{SPACE}0%{SPACE}:%{SPACE}SPCBId%{SPACE}%{INT:SPCBId}%{SPACE}-%{SPACE}ClientIP%{SPACE}%{IPV4:IP_origen}%{SPACE}-%{SPACE}ClientPort%{SPACE}%{NUMERO:Puerto_origen}%{SPACE}-%{SPACE}VserverServiceIP%{SPACE}%{IPV4:vServer_ip}%{SPACE}-%{SPACE}VserverServicePort%{SPACE}%{NUMERO:vServer_puerto}%{SPACE}-%{SPACE}ClientVersion%{SPACE}%{DATTERO:Client_version}%{SPACE}-%{SPACE}CipherSuite%{SPACE}\"%{DATTERO:Cipher_suite}\"(%{SPACE}-%{SPACE}Session%{SPACE}Reuse%{SPACE}-%{SPACE}HandshakeTime%{SPACE}%{INT:Handshake_time}%{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}%{PAROLA:Log_tipo}%{SPACE}%{PAROLA:Log_evento}%{SPACE}%{INT:Log_id}%{SPACE}0%{SPACE}:%{SPACE}SPCBId%{SPACE}%{INT:SPCBId}%{SPACE}-%{SPACE}IssuerName%{SPACE}\"%{SPACE}%{DATTERO:Issuer_name}\"", "^<%{POSINT:syslog_pri}>%{SPACE}%{DATE_US:Log_fecha}:%{TIME:Log_hora}%{SPACE}%{SYSLOGHOST:NSlog_hostname}%{SPACE}0-PPE-0%{SPACE}:%{SPACE}default%{SPACE}%{PAROLA:Log_tipo}%{SPACE}%{PAROLA:Log_evento}%{SPACE}%{INT:Log_id}%{SPACE}0%{SPACE}:%{SPACE}SPCBId%{SPACE}%{INT:SPCBId}%{SPACE}-%{SPACE}SubjectName%{SPACE}\"%{SPACE}%{DATTERO:Subject_name}\"", "^<%{POSINT:syslog_pri}>%{SPACE}%{DATE_US:Log_fecha}:%{TIME:Log_hora}%{SPACE}%{SYSLOGHOST:NSlog_hostname}%{SPACE}0-PPE-0%{SPACE}:%{SPACE}default%{SPACE}%{PAROLA:Log_tipo}%{SPACE}%{PAROLA:Log_evento}%{SPACE}%{INT:Log_id}%{SPACE}0%{SPACE}:%{SPACE}Context%{SPACE}%{NOME UTENTE:Utente}@%{IPV4:IP_origen}%{SPACE}-%{SPACE}SessionId:%{SPACE}%{INT:Session_id}%{SPACE}-%{SPACE}%{NOME HOST:FQDN}%{SPACE}User%{SPACE}%{NOME UTENTE:Usuario2}%{SPACE}:%{SPACE}Group\(s\)%{SPACE}%{DATTERO:Gruppo}%{SPACE}:%{SPACE}Vserver%{SPACE}%{IPV4:vServer_ip}:%{NUMERO:vServer_puerto}%{SPACE}-%{SPACE}%{DATE_US:Dattero}:%{TIME:Hora}%{SPACE}:%{SPACE}%{DATI GREEDYDATA:Messaggio}", "^<%{POSINT:syslog_pri}>%{SPACE}%{DATE_US:Log_fecha}:%{TIME:Log_hora}%{SPACE}%{SYSLOGHOST:NSlog_hostname}%{SPACE}0-PPE-0%{SPACE}:%{SPACE}default%{SPACE}%{PAROLA:Log_tipo}%{SPACE}%{PAROLA:Log_evento}%{SPACE}%{INT:Log_id}%{SPACE}0%{SPACE}:%{SPACE}%{DATI GREEDYDATA:Messaggio}" ] } } geoip { source => "IP_origen" target => "geoip" add_field => [ "[geoip][coordinates]", "%{[geoip][Longitudine]}" ] add_field => [ "[geoip][coordinates]", "%{[geoip][Latitudine]}" ] } mutate { convert => [ "[geoip][coordinates]", "galleggiare" ] convert => [ "Total_bytes_enviados", "Numero intero" ] convert => [ "Total_bytes_recibidos", "Numero intero" ] } } } prodotto { se ([digitare]=="Netscaler"){ Ricerca elastica { indice => "netscaler-%{+AAAA. MM.dd}" hosts=> "DIRECCION_IP_ELASTICSEARCH:9200" } } }
Así que creamos por ejemplo el siguiente fichero de configuración ‘/etc/logstash/conf.d/netscaler.conf’, yo os dejo mi ejemplo aquí abajo. Mis filtros son muy básicos y de primero de Logstash, pero funcionan 😉 así que si te interesan puedes copiarlos, y si los mejoras me los pasas 🙂 Al final indicaremos en la salida el servidor de Elasticsearch donde mandar los datos y el índice donde se almacenará; recordar que si tenéis autenticación poner los parámetros de ‘username’ & ‘password’ en el output. La verdad que estoy viendo ahora el código y es bastante mejorable, me rayé con los espacios recuerdo… espero me podáis perdonar pero funciona, al menos con las últimas versiones como pueda ser NetScaler 13.0.
Una volta creato il file di configurazione, ricordarsi di riavviare il servizio Logstash per ricaricarlo. Dopo come sempre, iremos a Kibana y una vez los datos estén entrando ya podremos ir a “Gestione” > “Stack management” > “Kibana” > “Modelli di indice” > “Creare un modello di indice” para crear el patrón del índice, Come ho detto, come al solito (in questo caso e senza virgolette) ‘netscaler-*’ y tendremos los datos ya en Elasticsearch almacenados de manera correcta. Ora potremmo connetterci da “Scoprire” a nuestro índice de NetScaler y visualizar que está recogiendo datos.
E poi, dopo aver creato l'indice in Kibana, ahora en nuestro Grafana deberíamos crear un “Data Source” que apunte contra nuestro Elasticsearch y el índice de NetScaler. Allora si tratta di dare libero sfogo alla tua immaginazione, creare una Dashboard con diverse Dashboard, con dati diversi da visualizzare, Uno Mappa del mondo con las conexiones entrantes, Uno di stile Sankey per visualizzare gli IP di origine/destinazione e il traffico inviato, in formato colonna, in stallo per visualizzare dati specifici, ad esempio i login corretti, Scorretto, Le connessioni…
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, Mettere un aggiornamento automatico ogni 10 secondi è molto impressionante, también nos servirá para analizar el resumen de una jornada, o conocer cuando algo extraño sucede… Come al solito, gracias a todos y más a los que movéis este tipo de contenidos en redes sociales 😉