Tutoriales y Manuales
Entradas Mensuales
-
▼
2024
(Total:
976
)
-
▼
noviembre
(Total:
24
)
- Apple presenta Share Item Location, la función par...
- Microsoft cambiará actualizaciones de Windows para...
- D-Link no solucionará una vulnerabilidad crítica q...
- Polvo cerámico mejora hasta un 72% el rendimiento ...
- Concatenación de ficheros comprimidos para infecta...
- Filtran datos de empleados de Amazon, McDonald's, ...
- El código IUA escrito en la roseta de fibra óptica...
- Fibra luminosa, descubierta por accidente, podría ...
- Canadá prohíbe el uso de TikTok
- Google tumbó la web de este matrimonio por hacerle...
- Visualizar con Grafana los eventos del IDS/IPS Sur...
- China está usando la IA de Meta para fines militares
- Multa de 85 millones a Telefónica en Estados Unido...
- Vulnerabilidad API de la web de Kia permitió a ata...
- Google revela el primer fallo de seguridad descubi...
- La IA llega a Paint y Notepad en Windows 11
- Alemania redacta una ley para proteger a los inves...
- Microsoft ralentizó el Panel de Control de Windows...
- Guías Equivalencias de procesadores Intel y AMD [G...
- Roban 15 mil credenciales en Git y hay 10 mil repo...
- Publican información del creador del infostealer "...
- Vulnerabilidad RCE en MS SharePoint explotada acti...
- Panel de Control Grafana para el WAF de Apache-Ngi...
- Cómo visualizar los registros de Apache/Nginx en m...
- ► septiembre (Total: 50 )
-
▼
noviembre
(Total:
24
)
-
►
2023
(Total:
710
)
- ► septiembre (Total: 65 )
-
►
2022
(Total:
967
)
- ► septiembre (Total: 72 )
-
►
2021
(Total:
730
)
- ► septiembre (Total: 56 )
-
►
2020
(Total:
212
)
- ► septiembre (Total: 21 )
-
►
2019
(Total:
102
)
- ► septiembre (Total: 14 )
-
►
2017
(Total:
231
)
- ► septiembre (Total: 16 )
-
►
2016
(Total:
266
)
- ► septiembre (Total: 38 )
-
►
2015
(Total:
445
)
- ► septiembre (Total: 47 )
-
►
2014
(Total:
185
)
- ► septiembre (Total: 18 )
-
►
2013
(Total:
100
)
- ► septiembre (Total: 3 )
-
►
2011
(Total:
7
)
- ► septiembre (Total: 1 )
Blogroll
Etiquetas
Entradas populares
-
Después de ver qué es una vCPU y la diferencia entre núcleos (cores) e hilos en los procesadores, pasamos a explicar toda la nomenclatura d...
-
Un grupo de investigadores en ciberseguridad ha descubierto una campaña masiva que se aprovecha de configuraciones inseguras de Git , esté e...
-
Un Actor de Amenazas que opera bajo el nombre de usuario Nam3L3ss ha explotado una vulnerabilidad crítica en MOVEit de 2023, un software ...
Cómo visualizar los registros de Apache/Nginx en modo gráfico con Grafana
Loki necesita un agente que puede enviar el registro de varias fuentes a la misma. Ahí es donde Promtail (o Grafana Agent) entra en escena. La instalación de Promtail es bastante sencilla, al igual que la instalación de Loki. Una vez que hayas configurado Loki y Promtail, ¡has terminado en un 50%!
Configuración de Promtail
Promtail es un agente de agregación de registros que se encarga de recopilar, procesar y reenviar los registros de diferentes fuentes como archivos o servicios a Loki. Como agente, actúa en el origen de los registros, recopilando y enviándolos a Loki, y puede adjuntar etiquetas para una mejor organización de los registros. organización de los registros.curl -s https://api.github.com/repos/grafana/loki/releases/latest | grep browser_download_url | cut -d '"' -f 4 | grep promtail-linux-amd64.zip | wget -i -
unzip promtail-linux-amd64.zip
sudo mv promtail-linux-amd64 /usr/local/bin/promtail
promtail --version
Instalar servicio promtail
sudo tee /etc/systemd/system/promtail.service<<EOF
[Unit]
Description=Promtail service
After=network.target
[Service]
Type=simple
User=root
ExecStart=/usr/local/bin/promtail -config.file /etc/promtail/config.yml
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl start promtail.service
systemctl status promtail.service
Como se mencionó anteriormente, Promtail está configurado para recuperar los registros de los archivos (archivos de registro) o servicios, y luego empujarlos a Loki.
Este es el ejemplo de configuración de Promtail para Apache :
Fichero /etc/promtail/config.yml
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://localhost:3100/loki/api/v1/push
scrape_configs:
- job_name: apache
static_configs:
- targets:
- localhost
labels:
job: apache
__path__: /var/log/apache2/access.log
Para el syslog
scrape_configs:
- job_name: system
pipeline_stages:
static_configs:
- targets:
- localhost
labels:
job: syslog
__path__: /var/log/syslog
Ejemplo configuración para log de ModSecurity
- job_name: modsecY el pattern:
static_configs:
- targets:
- localhost
labels:
job: modsec
__path__: /var/log/modsec_audit.log
{job="modsec", filename="/var/log/modsec_audit.log"} |= "ModSecurity"
| pattern `<_> [file "<file>"] [line "<line>"] [id "<id>"] [rev "<rev>"] [msg "<msg>"] [data "<data>"] [severity "<severity>"] [ver "<ver>"] [maturity "<maturity>"] [accuracy "<accuracy>"] <tag> [hostname "<hostname>"] [uri "<uri>"] [unique_id "<unique_id>"] [ref "<ref>"]`
O bien:
{job="modsec", filename="/var/log/modsec_audit.log"} |= "ModSecurity"
| pattern `<_> [file "<file>"] [line "<line>"] [id "<id>"] [rev "<rev>"] [msg "<msg>"] [data "<data>"] [severity "<severity>"] [ver "<ver>"] [maturity "<maturity>"] [accuracy "<accuracy>"] <tag> [hostname "<hostname>"] [uri "<uri>"] [unique_id "<unique_id>"] [ref "<ref>"]`
| label_format rules=`{{.file | replace "/etc/nginx/owasp-crs/rules/REQUEST-" "" | replace ".conf" ""}}`
| label_format tag=`{{.tag | replace "tag " "" | replace "] [" ","}}`
A continuación se muestra una configuración sencilla
- scrape_configs: Define de dónde se están recopilando los registros.
- job_name: Una etiqueta para la tarea de raspado.
- static_configs: Especifica la ubicación exacta de los registros que se van a recopilar.
- targets: Enumera los sistemas de los que se recopilarán los registros.
- labels: Etiquetas aplicadas a los registros. Esto mejora la clasificación y ayuda a la investigación cuando se analizan los registros.
- path: La ruta del archivo desde el que se leen los registros.
- client: El servidor Loki se especifica como la variable URL, aquí es donde Promtail empuja el registro.
También podemos usar labels para enumerar los campos del log (registro) de Apache o Nginx;
- job_name: apacheDe esta manera tenemos las etiquetas ip, action, path, protocol, status_code y useragent que podemos usar después para las consultas.
pipeline_stages:
- regex:
expression: ^(?P<ip>\\S+) (?P<identd>\\S+) (?P<user>\\S+) \\[(?P<timestamp>[\\w:/]+\\s[+\\-]\\d{4})\\] \"(?P<action>\\S+)\\s?(?P<path>\\S+)?\\s?(?P<protocol>\\S+)?\" (?P<status_code>\\d{3}|-) (?P<size>\\d+|-)\\s?\"?(?P<referer>[^\"]*)\"?\\s?\"?(?P<useragent>[^\"]*)?\"?$
- labels:
ip:
action:
path:
protocol:
status_code:
useragent:
static_configs:
- targets:
- localhost
labels:
job: apache
__path__: /var/log/apache2/access.log
Instalar Loki
sudo mkdir /opt/loki
cd /opt/loki
wget https://raw.githubusercontent.com/grafana/loki/v2.2.1/cmd/loki/loki-local-config.yaml
curl -O -L "https://github.com/grafana/loki/releases/download/v2.2.1/loki-linux-amd64.zip"
# Extract the binary
unzip "loki-linux-amd64.zip"
# Make sure it is executable
chmod a+x "loki-linux-amd64"
# Download config file
wget https://raw.githubusercontent.com/grafana/loki/v2.2.1/cmd/loki/loki-local-config.yaml
sudo mv loki-linux-amd64 /usr/local/bin/loki
Iniciar servicio Loki
sudo tee /etc/systemd/system/loki.service<<EOF
[Unit]
Description=Loki service
After=network.target
[Service]
Type=simple
User=root
ExecStart=/usr/local/bin/loki -config.file /etc/loki/config.yml
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl start loki.service
Este es el ejemplo de configuración de Loki como referencia:
Fichero /etc/loki/config.yml
auth_enabled: false
server:
http_listen_port: 3100
grpc_listen_port: 9096
common:
path_prefix: /tmp/loki
storage:
filesystem:
chunks_directory: /tmp/loki/chunks
rules_directory: /tmp/loki/rules
replication_factor: 1
ring:
instance_addr: 127.0.0.1
kvstore:
store: inmemory
schema_config:
configs:
- from: 2020-10-24
store: boltdb-shipper
object_store: filesystem
schema: v11
index:
prefix: index_
period: 24h
limits_config:
enforce_metric_name: false
reject_old_samples: true
reject_old_samples_max_age: 168h
chunk_store_config:
max_look_back_period: 0s
table_manager:
retention_deletes_enabled: false
retention_period: 0s
Lenguaje de consulta LogQL de Loki
Loki utiliza LogQL, el lenguaje de consulta Log, para proporcionarle el resultado esperado de los archivos de registro. Puedes consultar la documentación aquí
Sin embargo, si usted es perezoso para ir a través de los documentos, permítame ayudarle mencionando un par de información importante sobre LogQL de los documentos.
LogQL usa etiquetas y operadores para filtrar
Hay dos tipos de consultas LogQL:
Las consultas Log devuelven el contenido de las líneas de registro.
Las consultas métricas extienden las consultas log para calcular valores basados en los resultados de la consulta. (NOTA: Nos centraremos más en esto en este post)
Loki tiene diferentes operadores
1. Operadores Aritméticos
- + (addition)
- - (subtraction)
- * (multiplication)
- / (division)
- % (modulo)
- ^ (power/exponentiation)
Ejemplo: Para obtener la proporción de registros de advertencia a los registros de error para la aplicación foo:
sum(rate({app="foo", level="warn"}[1m])) / sum(rate({app="foo", level="error"}[1m]))
2. Operadores lógicos y de conjunto
- and (intersección)
- o (unión)
- unless (complemento)
Ejemplo: para obtener la intersección de estas consultas, efectivamente rate({app=«bar»}):
rate({app=~«foo|bar»}[1m]) y rate({app=«bar»}[1m])
3. Operadores de comparación
- == (igualdad)
- != (desigualdad)
- > (mayor que)
- >= (mayor o igual que)
- < (menor que)
- <= (menor o igual que)
Ejemplo: Filtrar los flujos que han registrado al menos 10 líneas en el último minuto:
count_over_time({foo=«bar»}[1m]) > 10
Obtenga su archivo de registro de acceso Apache/Nginx
Si tiene a mano el archivo de registro de acceso de Apache/nginx, eche un vistazo a su contenido y formato. Puede que tenga este aspecto :2. Operadores lógicos y de conjunto
and (intersección)
or (unión)
unless (complemento)
Ejemplo: para obtener la intersección de estas consultas, efectivamente rate({app=«bar»}):
rate({app=~«foo|bar»}[1m]) y rate({app=«bar»}[1m])
3. Operadores de comparación
- == (igualdad)
- != (desigualdad)
- > (mayor que)
- >= (mayor o igual que)
- < (menor que)
- <= (menor o igual que)
Ejemplo: Filtrar los flujos que han registrado al menos 10 líneas en el último minuto:
count_over_time({foo=«bar»}[1m]) > 10
Obtener archivo de registro de acceso Apache/Nginx
Si tiene a mano el archivo de registro de acceso de Apache/nginx, eche un vistazo a su contenido y formato. Puede tener este aspecto :
127.0.0.1 - - [01/Jan/2024:10:30:00 +0000] "GET /index.html HTTP/1.1" 200 1234 "https://www.example.com" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.1234.567 Safari/537.36" "-"
Explicación de todos los campos por orden:
- Host remoto (127.0.0.1): La dirección IP o el nombre de host del cliente que realiza la solicitud.
- Identidad del usuario remoto (-): Normalmente, este campo está vacío o contiene un guión (-). Se utiliza para la autenticación de usuarios en algunas configuraciones, pero a menudo no se utiliza.
- Nombre de usuario del usuario remoto (-): Similar al campo anterior, suele estar vacío o contener un guión (-) y también está relacionado con la autenticación de usuario.
- Timestamp ([01/Jan/2024:10:30:00 +0000]): La fecha y hora de la solicitud en el formato [día/mes/año:hora:minuto:segundo zona horaria].
- Línea de solicitud («GET /index.html HTTP/1.1»): El método de solicitud HTTP (GET en este caso), el recurso solicitado (/index.html) y la versión del protocolo HTTP (HTTP/1.1).
- Código de estado (200): El código de estado HTTP devuelto por el servidor que indica el éxito o el fracaso de la solicitud (200 significa éxito).
- Tamaño de la respuesta (1234): El tamaño de la respuesta enviada por el servidor al cliente en bytes.
- Referrer («https://www.example.com»): La URL de la página web que remitió al cliente al servidor.
- User-Agent («Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.1234.567 Safari/537.36»): Información sobre el agente de usuario del cliente (navegador, sistema operativo, versión, etc.).
- Campos adicionales («-»): Puede incluir otros campos opcionales o información adicional configurada en el formato del registro. En este ejemplo, es un marcador de posición.
Un vistazo a Grafana
Grafana, como ya he dicho y puede que ya sepas, ¡es una popular herramienta de visualización!
En OSS Grafana, puedes encontrar estas características:
Por ahora, tenemos que centrarnos en Dashbords, Explore, y Connection (Tal vez Alerting en un post aparte)
Una vez que instales Grafana, y mires en su página, lo primero que tienes que hacer es añadir Loki como Datasource en Conexiones - -> Añadir nueva conexión como puedes ver en la imagen de arriba.
Una vez que hayas introducido la URL de Loki, puedes desplazarte hacia abajo y hacer clic en el botón Save & test. Y si la URL es correcta y todo está bien, entonces Grafana puede añadir Loki como fuente de datos y estamos listos para el siguiente paso.
El siguiente paso sería probar si estamos recibiendo el registro de acceso de Apache. Eso lo podemos hacer navegando a la sección Explorar:
Como ya se mencionó, el archivo de registro de acceso de Apache contiene varios campos y necesitamos construir algunos visuales útiles en Grafana como compartí anteriormente usando la capacidad de Loki para crear etiquetas y usarlas en su consulta de métricas LogQL.
Antes de pasar a la consulta LogQL, echemos un vistazo a cómo consultamos y filtramos en LogQL en la sección Explorar
Ejemplo 1:
Si quiero ver el apache accesss log en Grafana, entonces tengo que escribir:
{job=«apache»}
o
{filename=«/var/log/apache2/access.log»}
Ambas consultas me darán la misma línea de salida del registro de acceso de Apache.
Ejemplo 2:
Si sólo quiero las líneas de registro que contienen el método GET:
{job=«apache»} |= `GET`
Ejemplo 3:
Si no quiero ver las líneas de registro que contienen el método POST:
{job=«apache»} != `POST`
Ahora que ya tenemos una idea de cómo consultar y filtrar, pasemos a la consulta y a la creación de etiquetas utilizando el analizador de patrones
Como el registro de Apache contiene el mismo archivo, podemos crear una etiqueta usando el analizador de patrones así:
pattern `<> - - [<_>] "<_> <_> <_>" <_> <_> "<_>" "<_>"`
Creating labels:
pattern `<ip> - - [<dttm>] "<method> <resource> <protocol>" <status> <object_size> "<referer>" "<user_agent>"`
Ahora se añade a la consulta:
{job="apache"} | pattern `<ip> - - [<dttm>] "<method> <resource> <protocol>" <status> <object_size> "<referer>" "<user_agent>"`
Esta consulta nos dará la línea de registro con todas las etiquetas como IP, Método, Estado, etc...
Una vez que lo conseguimos, podemos modificar la consulta en función de nuestros requisitos para crear algunos visuales útiles e interesantes como el que he compartido anteriormente.
Consultas detrás de las imágenes
Hay muchas cosas que podemos hacer, ¡pero veamos algunas métricas importantes para tomar medidas!
Consulta-1: Obtener el número total de peticiones GET/POST en un periodo de 5 minutos.
sum(count_over_time({job="apache"} | pattern `<_> - - <_> "<method> <_> <_>" <_> <_> <_> "<_>" <_>` | method=~"GET" [5m]))
Como sólo necesitamos saber el número del método Get (puedes hacer lo mismo para otros métodos como POST,PUT etc), por lo que no necesitamos etiquetar todos los campos excepto el del método. Y así es como resulta:
Si hemos usado las etiquetas (labels) en Loki en promtail la consulta quedaría así (el method se llama action en la etiqueta que hemos puesto en /etc/promtail/config.yml)
sum(count_over_time({job="apache"} | action=~"GET" [5m]))
sum(count_over_time({job="apache"} | pattern `<_> - - <_> "<_> <_> <_>" <status> <_> <_> "<_>" <_>` | status=~"5.." [5m])) by(status)
Consulta-3: Obtener la tasa de error de 5xx y 4xx para un periodo de 5 min.
sum by(status) (count_over_time({job="apache"} | pattern `<_> - - <_> "<_> <_> <_>" <status> <_> <_> "<_>" <_>` | status=~"4..|5.." [5m])) / ignoring(status) group_left sum by (status) (count_over_time({job="apache"} [5m])) * 100
Consulta-4: Obtener el recuento de todos los Métodos con su respectivo Estado para un periodo de 5 min.
sum(count_over_time({job="apache"} | pattern `<_> - - <_> "<method> <_> <_>" <status> <_> <_> "<_>" <_>` [5m])) by (method, status)
Consulta-5: Obtener el recuento de estados de error 4xx/5xx por ruta para un periodo de 5 minutos
sum(count_over_time({job="apache"} | pattern `<_> - - <_> "<method> <_> <_>" <status> <_> <_> "<_>" <_>` [5m])) by (method, status)sum(count_over_time({job="apache"} | pattern `<_> - - <_> "<_> <path> <_>" <status> <_> <_> "<_>" <_>` | status!~"2..|3.." [5m])) by(status,path)
Aquí, en esta consulta, estamos excluyendo los códigos de estado 2xx y 3xx para que sólo podamos tener los códigos de error 4xx y 5xx. Sin embargo, en la siguiente imagen, no tengo ningún código de error 5xx, por lo que no se muestra ninguno.
Espero que tengas una idea clara después de ver estas cinco preguntas. Puedes hacer muchas mas como estas dependiendo de tus requerimientos como:
- Obtener las IPs del Host Remoto y el recuento de IPs únicas para conocer cualquier incidente relacionado con la seguridad.
- Conocer el número de recursos solicitados
- Para obtener más información sobre el User-Agent como cuántas solicitudes provienen de móviles y de escritorio, etc.
Fuentes:
0 comentarios :
Publicar un comentario
Los comentarios pueden ser revisados en cualquier momento por los moderadores.
Serán publicados aquellos que cumplan las siguientes condiciones:
- Comentario acorde al contenido del post.
- Prohibido mensajes de tipo SPAM.
- Evite incluir links innecesarios en su comentario.
- Contenidos ofensivos, amenazas e insultos no serán permitidos.
Debe saber que los comentarios de los lectores no reflejan necesariamente la opinión del STAFF.