Extraer las direcciones IP de todos los clientes de un servidor Web desde el log de accesos

Otro artículo para demostrar cómo, utilizando comandos simples, es posible procesar y obtener información útil de forma rápida y sencilla. En este caso veamos cómo obtener una lista de todas las direcciones IP de los clientes de un servidor Web Apache o Nginx.







Los servidores Web Apache y Nginx (como así también IIS) utilizan el formato de log NCSA Common Log Format para registrar las solicitudes de clientes y errores. El mismo utiliza el siguiente formato:

NCSA extended/combined log format:

"%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\""

Donde cada componente registra la siguiente información:

%h : dirección IP.

: dirección IP. %l : nombre de log (típicamente una barra dash ).

: nombre de log (típicamente una barra ). %u : nombre de usuario (si la solicitud fue autenticada, un dash en caso contrario).

: nombre de usuario (si la solicitud fue autenticada, un en caso contrario). %t : fecha y hora de la solicitud.

: fecha y hora de la solicitud. \"%r\" : solicitud entre comillas.

: solicitud entre comillas. %>s : estado final de la solicitud.

: estado final de la solicitud. %b : tamaño de la respuesta en bytes, excluyendo las cabeceras HTTP.

: tamaño de la respuesta en bytes, excluyendo las cabeceras HTTP. \"%{Referer}i\" : referrer entre comillas (URL desde donde se originó el acceso).

: entre comillas (URL desde donde se originó el acceso). \"%{User-agent}i\" : user-agent (software del cliente).

Por ejemplo, veamos una entrada de un log de accesos de Nginx en formato NCSA:

root@linuxito:/var/log/nginx# head -n 1 access-ssl.log 94.126.240.2 - - [04/Oct/2019:06:25:29 -0400] "GET /gnu-linux/nivel-medio/544-como-listar-todos-los-usuarios-en-mysql HTTP/1.1" 200 63794 "https://www.google.es/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" "-"

El cliente accedió desde la dirección IP 94.126.240.2 , el día 4 de octubre de 2019 a las 6:25 (hora local del servidor GMT-4), al recurso "/gnu-linux/nivel-medio/544-como-listar-todos-los-usuarios-en-mysql" vía el protocolo HTTP versión 1.1. El estado de la respuesta HTTP del servidor fue 200 OK, el tamaño de la respuesta fue de 63794 bytes. El acceso se originó desde la URL "https://www.google.es/" y el agente de usuario corresponde al navegador Google Chrome desde un sistema operativo Microsoft Windows.

Tal como se observa, es una buena cantidad de información la que se registra en el log para cada uno de los accesos al servidor Web.

Vayamos ahora al punto del artículo ¿cómo hago para obtener un listado de las direcciones IP de todos los clientes que han accedido al servidor?

Tal como se observa, la dirección IP es el primer campo de cada entrada, y los campos se encuentran separados por un espacio en blanco. De esta forma, es posible recurrir a la herramienta cut para recuperar sólo el primer campo ( -f1 ) delimitado por espacio en blanco ( -d' ' ) de cada línea en el archivo. Luego basta con ordenar la salida y retornar sólo las líneas únicas (omitiendo las líneas repetidas, para el caso de clientes que han accedido más de una vez):

cut -d' ' -f1 access.log | sort | uniq

Los pipes ( | ) tienen el objetivo de conectar la salida de un comando con la entrada del siguiente. De esta forma, cada comando procesa como entrada la salida producida por el comando anterior.

Por ejemplo:

root@linuxito:/var/log/nginx# cut -d' ' -f1 access-ssl.log | sort | uniq | head -n 10 100.43.81.122 103.40.8.120 108.174.2.214 109.167.78.44 115.84.92.76 116.202.106.130 116.203.242.145 131.228.48.70 136.243.202.162 13.66.139.0

En este caso además he optado por mostrar sólo las diez primeras líneas ( head -n 10 ).

Es posible filtrar aún más utilizando grep . ¿Qué pasa si necesitamos obtener la lista de direcciones IP que accedieron al servidor un día y hora en particular? Fácil, basta con filtrar el log buscando la cadena que corresponde con la fecha u hora específica.

Por ejemplo, lista de direcciones IP que accedieron el día 3 de octubre a las 4 de la tarde (hora local del servidor, que corresponde a la cadena "03/Oct/2019:16:*" según el formato de hora utilizado):

root@linuxito:/var/log/nginx# grep ' \[03/Oct/2019:16' access-ssl.log | cut -d' ' -f1 | sort | uniq | head -n 10 100.43.81.122 106.120.188.160 107.178.194.225 107.178.194.227 115.84.99.117 116.202.106.128 116.203.242.145 132.251.0.57 136.243.202.162 138.121.13.184

Referencias



Tal vez pueda interesarte

