Introducción
En este laboratorio exploraremos el comando head de Linux, una potente utilidad para previsualizar el comienzo de los archivos de texto. Imagina que eres un detective digital encargado de revisar rápidamente numerosos archivos para encontrar información importante. El comando head será tu lupa de confianza: te permitirá echar un vistazo al inicio de los archivos sin tener que abrirlos por completo.
Simularemos una situación en la que investigas una colección de archivos de registro de un servidor web con mucha actividad. Tu objetivo será examinar estos registros de forma eficiente para identificar posibles problemas y obtener información útil. A través de este ejercicio práctico aprenderás a utilizar el comando head con eficacia, agilizando y haciendo más eficiente la exploración de archivos.
Conceptos básicos de head
En este paso examinarás un archivo de registro sencillo para entender cómo funciona head.
Primero, ve al directorio del proyecto:
cd /home/labex/project
Ahora, utilicemos el comando head con un archivo llamado access.log:
head access.log
Deberías ver una salida similar a esta:
192.168.1.100 - - [01/Jan/2024:00:00:01 +0000] "GET /index.html HTTP/1.1" 200 1234
192.168.1.101 - - [01/Jan/2024:00:00:02 +0000] "GET /style.css HTTP/1.1" 200 567
192.168.1.102 - - [01/Jan/2024:00:00:03 +0000] "GET /logo.png HTTP/1.1" 200 2345
192.168.1.103 - - [01/Jan/2024:00:00:04 +0000] "POST /login HTTP/1.1" 302 -
192.168.1.104 - - [01/Jan/2024:00:00:05 +0000] "GET /dashboard HTTP/1.1" 200 3456
192.168.1.105 - - [01/Jan/2024:00:00:06 +0000] "GET /api/user HTTP/1.1" 200 789
192.168.1.106 - - [01/Jan/2024:00:00:07 +0000] "GET /images/banner.jpg HTTP/1.1" 200 4567
192.168.1.107 - - [01/Jan/2024:00:00:08 +0000] "POST /comment HTTP/1.1" 201 -
192.168.1.108 - - [01/Jan/2024:00:00:09 +0000] "GET /search?q=linux HTTP/1.1" 200 2345
192.168.1.109 - - [01/Jan/2024:00:00:10 +0000] "GET /about HTTP/1.1" 200 1234
De forma predeterminada, head muestra las primeras 10 líneas del archivo. Cada línea de este registro representa una solicitud al servidor web e incluye la dirección IP, la marca de tiempo, el método HTTP, el recurso solicitado, el código de estado y el tamaño de la respuesta.
Personalización del número de líneas
En este paso personalizarás el número de líneas que muestra head.
Para ver únicamente las primeras 5 líneas del registro, utiliza la opción -n:
head -n 5 access.log
El comando debería mostrar:
192.168.1.100 - - [01/Jan/2024:00:00:01 +0000] "GET /index.html HTTP/1.1" 200 1234
192.168.1.101 - - [01/Jan/2024:00:00:02 +0000] "GET /style.css HTTP/1.1" 200 567
192.168.1.102 - - [01/Jan/2024:00:00:03 +0000] "GET /logo.png HTTP/1.1" 200 2345
192.168.1.103 - - [01/Jan/2024:00:00:04 +0000] "POST /login HTTP/1.1" 302 -
192.168.1.104 - - [01/Jan/2024:00:00:05 +0000] "GET /dashboard HTTP/1.1" 200 3456
Esto resulta especialmente útil cuando buscas información concreta cerca del principio de un archivo, pero no necesitas consultar las 10 líneas completas.
Examen de varios archivos
En este paso utilizarás head para consultar simultáneamente el inicio de varios archivos.
Examinemos el comienzo de access.log y error.log:
head access.log error.log
Deberías ver una salida similar a esta:
==> access.log <==
192.168.1.120 - - [01/Jan/2024:00:00:53 +0000] "POST /about HTTP/1.1" 200 7616
192.168.1.147 - - [01/Jan/2024:00:00:45 +0000] "GET /dashboard HTTP/1.1" 200 7348
192.168.1.138 - - [01/Jan/2024:00:00:03 +0000] "DELETE /comment HTTP/1.1" 400 8341
192.168.1.138 - - [01/Jan/2024:00:00:31 +0000] "DELETE /about HTTP/1.1" 200 3254
192.168.1.122 - - [01/Jan/2024:00:00:15 +0000] "PUT /index.html HTTP/1.1" 500 6061
192.168.1.125 - - [01/Jan/2024:00:00:09 +0000] "DELETE /logo.png HTTP/1.1" 301 4916
192.168.1.148 - - [01/Jan/2024:00:00:33 +0000] "POST /admin/dashboard HTTP/1.1" 201 5546
192.168.1.146 - - [01/Jan/2024:00:00:56 +0000] "GET /images/banner.jpg HTTP/1.1" 301 2332
192.168.1.195 - - [01/Jan/2024:00:00:12 +0000] "DELETE /dashboard HTTP/1.1" 404 6740
192.168.1.136 - - [01/Jan/2024:00:00:18 +0000] "GET /login HTTP/1.1" 200 2374
==> error.log <==
[01/Jan/2024:00:01:23 +0000] [error] [client 192.168.1.150] File does not exist: /var/www/html/missing.html
[01/Jan/2024:00:02:34 +0000] [error] [client 192.168.1.151] PHP Parse error: syntax error, unexpected ';' in /var/www/html/index.php on line 30
[01/Jan/2024:00:03:45 +0000] [warn] [client 192.168.1.152] ModSecurity: Access denied with code 403 (phase 2). Matched phrase "sql injection attempt" at REQUEST_URI. [file "/etc/modsecurity/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf"] [line "50"] [id "942100"] [rev ""] [msg "SQL Injection Attack Detected via libinjection"] [data "Matched Data: SQL injection found within REQUEST_URI: /vulnerable.php?id=1'"] [severity "CRITICAL"] [ver "OWASP_CRS/3.3.0"] [maturity "0"] [accuracy "0"] [hostname "example.com"] [uri "/vulnerable.php"] [unique_id "YvKp2H8AAQEAAAxxBGIAAAAC"]
[01/Jan/2024:00:04:56 +0000] [error] [client 192.168.1.153] AH01071: Got error 'PHP message: PHP Fatal error: Uncaught Error: Call to undefined function mysql_connect() in /var/www/html/db.php:15...'
[01/Jan/2024:00:05:67 +0000] [warn] [client 192.168.1.154] ModSecurity: Warning. Matched "Operator \`Ge' with parameter \`5' against variable \`TX:ANOMALY_SCORE' (Value: \`5' ) [file "/etc/modsecurity/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "57"] [id "949110"] [rev ""] [msg "Inbound Anomaly Score Exceeded (Total Score: 5)"] [data ""] [severity "CRITICAL"] [ver "OWASP_CRS/3.3.0"] [maturity "0"] [accuracy "0"] [hostname "example.com"] [uri "/admin"] [unique_id "YvKp2H8AAQEAAAxxBGIAAAAD"]
[01/Jan/2024:00:06:78 +0000] [error] [client 192.168.1.155] PCE: Can't open perl script "/var/www/html/cgi-bin/printenv": No such file or directory
[01/Jan/2024:00:07:89 +0000] [warn] [client 192.168.1.156] ModSecurity: Access denied with code 403 (phase 2). Matched phrase "directory traversal attempt" at ARGS:file. [file "/etc/modsecurity/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf"] [line "75"] [id "930110"] [rev ""] [msg "Path Traversal Attack (/../)"] [data "Matched Data: ../ found within ARGS:file: ../../../etc/passwd"] [severity "CRITICAL"] [ver "OWASP_CRS/3.3.0"] [maturity "0"] [accuracy "0"] [hostname "example.com"] [uri "/download.php"] [unique_id "YvKp2H8AAQEAAAxxBGIAAAAE"]
[01/Jan/2024:00:08:90 +0000] [error] [client 192.168.1.157] PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 20480 bytes) in /var/www/html/memory_hog.php on line 10
[01/Jan/2024:00:09:01 +0000] [warn] [client 192.168.1.158] ModSecurity: Warning. Pattern match "(?i:(?:[\s'\"`_''\(\)]*?(?:[\d\w]+[\s'\"`_''\(\)]*?){2,}[\s'\"`_''\(\)]*?(?:having|rongjitest|select|union|where|get_lst))" at ARGS:username. [file "/etc/modsecurity/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf"] [line "1126"] [id "942480"] [rev ""] [msg "SQL Injection Attack"] [data "Matched Data: union select found within ARGS:username: admin' UNION SELECT password FROM users--"] [severity "CRITICAL"] [ver "OWASP_CRS/3.3.0"] [maturity "0"] [accuracy "0"] [hostname "example.com"] [uri "/login.php"] [unique_id "YvKp2H8AAQEAAAxxBGIAAAAF"]
[01/Jan/2024:00:10:12 +0000] [error] [client 192.168.1.159] AH01797: client denied by server configuration: /var/www/html/restricted/
Observa cómo head separa claramente la salida de cada archivo mediante encabezados. Esto resulta muy útil cuando necesitas comparar rápidamente el comienzo de varios archivos.
Uso de head con tuberías
En este paso combinarás head con otro comando mediante una tubería.
Supongamos que quieres ver las primeras 3 líneas de access.log, pero únicamente las partes que muestran la marca de tiempo y el recurso solicitado. Puedes utilizar el comando cut junto con head para lograrlo:
cut -d '"' -f2 access.log | head -n 3
El comando debería mostrar:
POST /about HTTP/1.1
GET /dashboard HTTP/1.1
DELETE /comment HTTP/1.1
La parte cut -d '"' -f2 access.log divide cada línea en las comillas y selecciona el segundo campo, que contiene la solicitud HTTP. El símbolo | envía esa salida a head -n 3, que muestra únicamente sus tres primeras líneas.
Esta combinación permite centrarse rápidamente en partes concretas de las entradas del registro, lo que hace que la investigación sea más ágil y eficiente.
Investigación con head y grep
En este paso combinarás head con grep para buscar un patrón específico en el registro.
Supón que has recibido avisos sobre actividad inusual relacionada con la página /admin. Quieres comprobar las primeras apariciones de /admin en el registro de accesos:
grep "/admin" access.log | head -n 3
El comando debería producir una salida similar a esta:
192.168.1.148 - - [01/Jan/2024:00:00:33 +0000] "POST /admin/dashboard HTTP/1.1" 201 5546
192.168.1.115 - - [01/Jan/2024:00:00:22 +0000] "PUT /admin HTTP/1.1" 302 1113
192.168.1.163 - - [01/Jan/2024:00:00:56 +0000] "POST /admin/dashboard HTTP/1.1" 301 815
La parte grep "/admin" access.log busca en access.log las líneas que contienen /admin. El símbolo | envía las líneas coincidentes a head -n 3, que muestra únicamente las tres primeras coincidencias.
Esta combinación permite centrarse rápidamente en las entradas relevantes del archivo de registro, haciendo que la investigación sea más específica y eficiente.
Exploración de archivos grandes con head
En este paso utilizarás head para examinar un archivo de registro grande sin cargar todo su contenido en memoria.
Simularemos el trabajo con un archivo grande utilizando access.log, el archivo que hemos estado manejando. Supondremos que es mucho más grande de lo que realmente es.
Primero, comprueba el tamaño del archivo:
ls -lh access.log
Ahora, utiliza head para ver las primeras 15 líneas:
head -n 15 access.log
Deberías ver una salida similar a la anterior, pero con 15 líneas en lugar de 10.
El comando head es rápido porque solo lee el principio del archivo y consume poca memoria porque no carga todo su contenido. Así puedes obtener una vista previa rápida de la estructura y el contenido del archivo.
Resumen
En este laboratorio exploramos el comando head, una herramienta muy útil para examinar rápidamente el comienzo de los archivos. Aprendimos a:
- Utilizar
headpara ver de forma predeterminada las primeras 10 líneas de un archivo. - Personalizar el número de líneas mostradas mediante la opción
-n. - Examinar varios archivos simultáneamente con
head. - Combinar
headcon otros comandos, comocutygrep, mediante tuberías. - Utilizar
headpara trabajar de forma eficiente con archivos grandes.
Otros parámetros de head que no se trataron en este laboratorio:
-c: muestra los primeros bytes de un archivo en lugar de las primeras líneas.-q: omite los encabezados al examinar varios archivos.-v: muestra siempre los encabezados al examinar varios archivos.



