1. Fundamentos de expresiones regulares en seguridad
En las tareas de bastionado y auditoría, la inspección manual de ficheros de configuración y registros de eventos resulta inviable por su volumen. Las expresiones regulares constituyen un lenguaje formal para describir patrones de texto y permiten localizar en segundos directivas mal configuradas, credenciales expuestas o evidencias de compromiso.
Su dominio es una competencia transversal del módulo: las mismas expresiones que se escriben con grep se reutilizan después en sed, awk, en los filtros de Fail2ban, en las reglas de detección de un SIEM o en las comprobaciones automatizadas de OpenSCAP.
1.1. Variantes de expresiones regulares
En los sistemas GNU/Linux conviven tres dialectos que conviene distinguir con precisión, ya que un mismo patrón puede tener significados distintos según el motor que lo interprete:
-
Expresiones regulares básicas o BRE (Basic Regular Expressions): Es el dialecto por defecto de
grepysed. Los caracteres+,?,{,},(,)y|son literales y solo adquieren significado especial al escaparlos. El estándar POSIX define\{n,m\}y\(\). Las formas\+,\?y\|son extensiones de GNU que no funcionan en otras implementaciones. -
Expresiones regulares extendidas o ERE (Extended Regular Expressions): Los operadores
+,?,{n,m},()y|funcionan sin escape, lo que produce patrones más legibles. Se activan congrep -Eysed -E, y son el dialecto nativo deawk. -
Expresiones compatibles con Perl o PCRE (Perl Compatible Regular Expressions): Añaden abreviaturas como
\d,\wy\s, cuantificadores perezosos, aserciones de anticipación y retrospección, y la secuencia\K, que descarta del resultado todo lo que la precede. En GNUgrepse activan con-P. No están disponibles ensedni enawk.
|
Una expresión regular no es un comodín de la shell En la shell, |
1.2. Metacaracteres fundamentales
| Metacarácter | Descripción | Ejemplo | Explicación técnica |
|---|---|---|---|
|
Anclaje de inicio de línea |
|
Solo coincide si la cadena aparece al principio de la línea, lo que descarta las versiones comentadas con |
|
Anclaje de fin de línea |
|
Solo coincide si la línea termina con la cadena, útil para clasificar intérpretes de órdenes en |
|
Cualquier carácter |
|
Coincide con cualquier carácter individual. Para buscar un punto literal, como en una dirección IP, debe escaparse: |
|
Cero o más repeticiones |
|
Repite el elemento anterior cualquier número de veces, incluida ninguna. |
|
Una o más repeticiones |
|
En ERE y PCRE exige al menos una aparición del elemento anterior. |
|
Cero o una repetición |
|
En ERE y PCRE convierte en opcional el elemento anterior. |
|
Repetición acotada |
|
En ERE exige entre |
|
Clase de caracteres |
|
Coincide con un único carácter de la lista o del intervalo. |
|
Clase negada |
|
Coincide con cualquier carácter que no esté en la lista. Es la forma idónea de recorrer un campo delimitado por |
|
Agrupación |
|
En ERE agrupa subpatrones para aplicarles un cuantificador o una alternancia. |
La alternancia se expresa en ERE y PCRE con la barra vertical, que actúa como disyunción entre subpatrones: (error|fail) coincide con cualquiera de las dos palabras. En BRE, GNU admite la forma escapada error\|fail.
1.3. Clases POSIX, límites de palabra y configuración regional
Los intervalos como [a-z] dependen de la configuración regional activa, o locale, y, en algunas de ellas, pueden incluir letras acentuadas o mayúsculas. Para que una auditoría produzca el mismo resultado en cualquier servidor se recomiendan las clases POSIX:
| Clase | Equivale a | Uso típico en bastionado |
|---|---|---|
|
Dígitos |
UID, GID, puertos, contadores |
|
Letras |
Nombres de directivas |
|
Letras y dígitos |
Identificadores y nombres de cuenta |
|
Espacio y tabulador |
Separación entre directiva y valor |
|
Espacio, tabulador, saltos de línea y retorno de carro |
Detección de líneas en blanco con |
|
Dígitos hexadecimales |
Huellas SHA-256, direcciones MAC |
Para buscar palabras completas, GNU proporciona las anclas \< y \>, así como \b, o bien la opción -w de grep. De este modo, buscar su no coincide con sudo ni con sshd_config.
|
Anteponer |
2. Sintaxis y opciones esenciales de grep
El nombre grep procede del comando g/re/p del editor ed: aplicar globalmente una expresión regular e imprimir las líneas que coinciden. La herramienta examina la entrada línea a línea y escribe en la salida estándar las que satisfacen el patrón.
grep [opciones] 'patrón' [fichero...]
grep [opciones] -e 'patrón1' -e 'patrón2' [fichero...]
grep [opciones] -f fichero_de_patrones [fichero...]
Si no se indica ningún fichero, grep lee de la entrada estándar, lo que permite usarlo como filtro dentro de una tubería.
2.1. Opciones clave
| Categoría | Opción | Efecto | Uso en bastionado |
|---|---|---|---|
Motor |
|
Usa ERE |
Patrones con alternancias o cuantificadores |
Motor |
|
Cadena literal, sin interpretar metacaracteres |
Búsqueda de listas de indicadores de compromiso, como direcciones o hashes, con |
Motor |
|
Usa PCRE |
Extracción precisa con |
Coincidencia |
|
Ignora mayúsculas y minúsculas |
Directivas de |
Coincidencia |
|
Solo palabras completas |
Evitar que |
Coincidencia |
|
La línea completa debe coincidir |
Validar el contenido exacto de una línea |
Coincidencia |
|
Invierte la selección |
Descartar comentarios y ruido |
Salida |
|
Muestra el número de línea |
Localizar la directiva para corregirla |
Salida |
|
Cuenta las líneas coincidentes |
Métricas rápidas de eventos |
Salida |
|
Muestra solo el fragmento coincidente |
Extraer direcciones IP, usuarios o rutas |
Salida |
|
Lista los ficheros con o sin coincidencias |
Inventario de ficheros que contienen o que carecen de un control |
Salida |
|
Oculta o fuerza el nombre del fichero |
Formatear la salida para tuberías |
Salida |
|
Silencioso, solo devuelve el código de salida |
Condiciones en scripts de auditoría |
Salida |
|
Suprime errores de ficheros inexistentes o ilegibles |
Rutas con comodines que pueden no existir |
Recursión |
|
Búsqueda recursiva; |
Barrido de |
Recursión |
|
Filtra por nombre de fichero |
Limitar el barrido a |
Recursión |
|
Ignora ficheros binarios |
Evitar falsos positivos en ejecutables |
Contexto |
|
Muestra |
Reconstruir la secuencia de un incidente |
|
Las órdenes |
2.2. Código de salida y uso en scripts
grep comunica su resultado mediante el código de salida, que es la base de cualquier comprobación automatizada:
| Código | Significado |
|---|---|
|
Se ha encontrado al menos una coincidencia |
|
No se ha encontrado ninguna coincidencia |
|
Se ha producido un error, como un fichero inexistente o sin permisos de lectura |
if sudo grep -qE '^[^:]+::' /etc/shadow; then
echo "NO CONFORME: existen cuentas sin contraseña"
else
echo "CONFORME"
fi
|
En un script de auditoría, el código |
|
Con los conceptos explicados hasta aquí, ya puede realizar el Ejercicio 1. Preparación del laboratorio y primeras búsquedas y el Ejercicio 2. Precisión de los patrones y falsos positivos. |
3. Inspección y auditoría de configuraciones
3.1. Extracción de la configuración activa
Los ficheros de configuración contienen numerosas líneas comentadas y en blanco. Para revisar únicamente las directivas operativas:
grep -vE '^[[:space:]]*(#|;|$)' /etc/ssh/sshd_config
-
^[[:space:]]*admite espacios, tabuladores o un retorno de carro al principio de la línea. -
(#|;|$)coincide con el inicio de un comentario o con el final de una línea vacía. El carácter;cubre ficheros de estilo INI, comophp.ini. -
-vinvierte la selección y conserva solo las líneas que no son comentarios ni líneas vacías.
3.2. Auditoría de directivas de OpenSSH
Una primera aproximación consiste en buscar las directivas en el fichero principal y en los ficheros incluidos:
sudo grep -HinsE '^[[:blank:]]*(PermitRootLogin|PasswordAuthentication|PermitEmptyPasswords)[[:blank:]]' \
/etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf
Sin embargo, este método no es concluyente. En OpenSSH, para la mayoría de directivas, prevalece el primer valor leído, y en Debian y Ubuntu la línea Include /etc/ssh/sshd_config.d/*.conf aparece al principio de sshd_config. Un fichero como 50-cloud-init.conf, que crean muchas imágenes de nube con PasswordAuthentication yes, anula cualquier valor posterior del fichero principal aunque grep muestre no en él.
La verificación fiable, y la que utiliza el propio CIS Benchmark, consulta la configuración efectiva que calcula el servicio:
sudo sshd -T | grep -iE '^(permitrootlogin|passwordauthentication|permitemptypasswords) '
|
Fichero de configuración frente a configuración efectiva
|
El CIS Benchmark exige PermitRootLogin no y PermitEmptyPasswords no. Desactivar PasswordAuthentication para admitir solo claves públicas es una medida de bastionado habitual, más estricta que el control equivalente del CIS, que debe aplicarse únicamente después de haber desplegado y probado las claves de los administradores.
3.3. Detección de claves privadas expuestas
El almacenamiento descuidado de claves privadas en directorios temporales, copias de seguridad o repositorios es una vía frecuente de acceso inicial y movimiento lateral, recogida en MITRE ATT&CK como Unsecured Credentials: Private Keys (T1552.004). La siguiente orden inventaría los ficheros que contienen una clave privada en formato PEM u OpenSSH:
sudo grep -rlIE -- '-----BEGIN ([A-Z]+ )*PRIVATE KEY( BLOCK)?-----' /home /root /tmp /var/tmp /srv /opt 2>/dev/null
-
-ldevuelve solo la ruta de cada fichero, sin volcar material sensible en la terminal ni en el historial de la sesión. -
-Idescarta ficheros binarios. -
--indica el final de las opciones, imprescindible porque el patrón empieza por un guion. -
El patrón cubre las cabeceras
RSA,EC,DSA,OPENSSH,ENCRYPTEDyPGP.
Cada resultado debe revisarse: comprobar sus permisos con stat, confirmar si la clave está cifrada con frase de paso y, si estuvo expuesta, revocarla y sustituirla.
|
Con los conceptos explicados en esta sección, ya puede realizar el Ejercicio 3. Auditoría de configuraciones y credenciales. |
4. Análisis de registros y detección de anomalías
4.1. Fuentes de registro de autenticación
La ubicación de los eventos de autenticación depende de la distribución:
-
Ubuntu y Debian con
rsyslog:/var/log/auth.log, con rotaciones enauth.log.1yauth.log.2.gz, entre otras. -
RHEL, Rocky Linux y Fedora:
/var/log/secure. -
Debian 12 y posteriores en instalación mínima: no instalan
rsyslog, de modo que los eventos solo están en el diario desystemd-journaldy se consultan conjournalctl.
# Equivalente a buscar en auth.log usando el diario de systemd
sudo journalctl -u ssh --since today --no-pager | grep 'Failed password'
# journalctl también puede filtrar por expresión regular con -g
sudo journalctl -u ssh --since '-1h' -g 'Failed password|Invalid user'
|
A partir de OpenSSH 9.8 la autenticación se gestiona en un proceso independiente, de modo que las líneas de registro aparecen con el identificador |
4.2. Anatomía de un evento de autenticación
Oct 18 08:01:20 srv01 sshd[1203]: Failed password for invalid user admin from 198.51.100.23 port 40022 ssh2 (1) (2) (3) (4) (5) (6)
| 1 | Marca temporal. En Ubuntu 24.04 y otras distribuciones recientes se registra en formato ISO 8601, como 2026-10-18T08:01:20.512345+02:00. |
| 2 | Nombre del equipo que genera el evento. |
| 3 | Proceso emisor y su PID. |
| 4 | Tipo de evento: autenticación fallida por contraseña. |
| 5 | Usuario objetivo. La cadena invalid user indica que la cuenta no existe, un indicio de enumeración de usuarios. |
| 6 | Dirección IP de origen de la conexión. |
4.3. Extracción de direcciones IP
La opción -o permite extraer solo la parte coincidente de cada línea:
sudo grep 'Failed password' /var/log/auth.log | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}'
Este patrón es suficiente para extraer direcciones de un registro fiable, pero también aceptaría valores imposibles como 999.999.999.999 y cualquier otra secuencia numérica similar que aparezca en el mensaje. Con PCRE se puede anclar la extracción al contexto exacto y obtener tanto direcciones IPv4 como IPv6:
sudo grep -oP 'Failed password for .* from \K[0-9a-fA-F:.]+' /var/log/auth.log
\K hace que la parte anterior del patrón actúe solo como contexto y no forme parte del resultado.
4.4. Registros rotados y comprimidos
Los registros antiguos se comprimen con gzip al rotarse. zgrep acepta las mismas opciones que grep y procesa indistintamente ficheros comprimidos y sin comprimir:
sudo zgrep -h 'Failed password' /var/log/auth.log*
4.5. Detección de patrones de ataque web
Los registros de acceso de Apache y Nginx almacenan la petición tal y como la envió el cliente, por lo que es necesario contemplar también las variantes codificadas en URL:
-
Recorrido de directorios o path traversal:
sudo grep -iE '(\.\./|\.\.\\|%2e%2e(%2f|%5c|/))' /var/log/nginx/access.log -
Sondeo de ficheros sensibles y paneles de administración:
sudo grep -iE '"(GET|POST|HEAD) [^"]*(phpmyadmin|wp-login\.php|/\.env|/\.git/)' /var/log/nginx/access.log -
Herramientas automatizadas identificadas por su agente de usuario:
sudo grep -iE '(sqlmap|nikto|nmap|zgrab|masscan|gobuster)' /var/log/nginx/access.log
|
Estas búsquedas son indicadores, no pruebas de compromiso. Un código de respuesta |
|
Con los conceptos explicados en esta sección, ya puede realizar el Ejercicio 4. Análisis forense de registros. |
5. Recetario de grep para el bastionado continuo
-
Cuentas con UID 0 distintas de
root:grep -E '^[^:]+:[^:]*:0:' /etc/passwd | grep -v '^root:'El patrón ancla el
0al tercer campo. Una búsqueda ingenua de:0:en toda la línea produce falsos positivos con cuentas cuyo GID es0. -
Directivas de caducidad de contraseñas y algoritmo de hash en
/etc/login.defs:grep -E '^[[:blank:]]*(PASS_MAX_DAYS|PASS_MIN_DAYS|PASS_WARN_AGE|ENCRYPT_METHOD|UMASK)[[:blank:]]' /etc/login.defs -
Cuentas sin contraseña:
sudo grep -E '^[^:]+::' /etc/shadow -
Módulos PAM que admiten contraseñas vacías:
grep -rnwE '^[^#]*nullok' /etc/pam.d/ -
Reglas de
sudosin solicitud de contraseña:sudo grep -rnE '^[^#]*NOPASSWD' /etc/sudoers /etc/sudoers.d/ -
Obtención de un intérprete de órdenes interactivo a través de
sudo:sudo grep -E 'COMMAND=(/usr)?/bin/((ba|da|z|k)?sh|su)( |$)' /var/log/auth.logUn patrón genérico como
COMMAND=.*shproduciría falsos positivos conssh,ssh-keygeno cualquier script.sh. -
Búsqueda de indicadores de compromiso (IOC) a partir de una lista:
sudo grep -hFwf ioc_ips.txt /var/log/auth.log /var/log/nginx/access.logCon
-Fy-f,grepbusca simultáneamente todas las cadenas literales del ficheroioc_ips.txt, una por línea, de forma mucho más eficiente que con una alternancia. La opción-wevita que10.0.0.1coincida con10.0.0.15.
|
Con el recetario anterior, ya puede realizar el Ejercicio 5. Script de comprobación de controles. |
6. Ejercicios prácticos
Los ejercicios deben realizarse en orden sobre una máquina virtual Debian o Ubuntu de pruebas. El último ejercicio elimina el laboratorio.
| Nº | Ejercicio | Competencia que desarrolla |
|---|---|---|
1 |
Usar las opciones básicas de |
|
2 |
Anclar patrones a campos concretos y evitar coincidencias espurias |
|
3 |
Distinguir entre configuración escrita y configuración efectiva |
|
4 |
Extraer indicadores de ataque de registros de autenticación y web |
|
5 |
Automatizar verificaciones mediante códigos de salida |
|
6 |
Revertir el laboratorio |
6.1. Ejercicio 1. Preparación del laboratorio y primeras búsquedas
Realice los siguientes pasos:
-
Cree la estructura del laboratorio y una copia de
/etc/passwda la que se añaden dos cuentas: una puerta trasera con UID 0 y una cuenta legítima cuyo GID es 0.mkdir -p ~/lab_filtrado/grep/{logs,ssh/sshd_config.d,tmp} cd ~/lab_filtrado/grep cp /etc/passwd passwd echo 'soporte:x:0:0:Soporte tecnico:/root:/bin/bash' >> passwd echo 'backup2:x:1501:0:Copias:/var/backups:/usr/sbin/nologin' >> passwd -
Cree el registro de autenticación de muestra
logs/auth.log:cat > logs/auth.log << 'EOF' Oct 18 08:00:01 srv01 CRON[1101]: pam_unix(cron:session): session opened for user root(uid=0) by (uid=0) Oct 18 08:01:12 srv01 sshd[1201]: Failed password for root from 203.0.113.45 port 51234 ssh2 Oct 18 08:01:15 srv01 sshd[1201]: Failed password for root from 203.0.113.45 port 51234 ssh2 Oct 18 08:01:19 srv01 sshd[1201]: Failed password for root from 203.0.113.45 port 51234 ssh2 Oct 18 08:01:20 srv01 sshd[1203]: Failed password for invalid user admin from 198.51.100.23 port 40022 ssh2 Oct 18 08:01:24 srv01 sshd[1203]: Failed password for invalid user admin from 198.51.100.23 port 40022 ssh2 Oct 18 08:01:30 srv01 sshd[1207]: Invalid user oracle from 198.51.100.23 port 40030 Oct 18 08:01:31 srv01 sshd[1207]: Failed password for invalid user oracle from 198.51.100.23 port 40030 ssh2 Oct 18 08:01:40 srv01 sshd[1209]: Failed password for operador from 192.0.2.10 port 50098 ssh2 Oct 18 08:02:01 srv01 sshd[1210]: Accepted password for operador from 192.0.2.10 port 50100 ssh2 Oct 18 08:03:44 srv01 sudo: operador : TTY=pts/0 ; PWD=/home/operador ; USER=root ; COMMAND=/usr/bin/apt update Oct 18 08:04:10 srv01 sudo: operador : TTY=pts/0 ; PWD=/home/operador ; USER=root ; COMMAND=/bin/bash Oct 18 08:04:30 srv01 sudo: operador : TTY=pts/0 ; PWD=/home/operador ; USER=root ; COMMAND=/usr/bin/ssh-keygen -A Oct 18 08:05:02 srv01 sshd[1250]: Failed password for root from 203.0.113.45 port 51302 ssh2 Oct 18 08:05:09 srv01 sshd[1250]: Failed password for root from 203.0.113.45 port 51302 ssh2 Oct 18 08:07:12 srv01 sshd[1290]: Accepted password for root from 203.0.113.45 port 51400 ssh2 EOF -
Muestre las líneas de
logs/auth.logque contienenFailed password, con su número de línea, y después solo su recuento. -
Muestre las cuentas de
passwdcuyo intérprete es/bin/bash. Repita la búsqueda mostrando únicamente las líneas que no terminan ennologinni enfalse. -
Muestre las dos líneas anteriores y la línea posterior al evento
Accepted password for root. Razone qué sugiere esa secuencia.
6.2. Ejercicio 2. Precisión de los patrones y falsos positivos
Realice los siguientes pasos:
-
Ejecute la búsqueda ingenua
grep ':0:' passwdy compárela con un patrón anclado al tercer campo. Explique por qué aparecebackup2en el primer caso. -
Busque en
logs/auth.loglos comandos ejecutados consudoque contienenshcon el patrónCOMMAND=.*shy, a continuación, con el patrón preciso del recetario. Identifique el falso positivo. -
Compruebe la diferencia entre
grep root logs/auth.log,grep -w root logs/auth.logygrep -cde ambos. ¿Por qué coinciden en este caso? Construya una línea de prueba conchrootque demuestre la diferencia.
6.3. Ejercicio 3. Auditoría de configuraciones y credenciales
Realice los siguientes pasos:
-
Cree una configuración de SSH de muestra que reproduce el comportamiento de una imagen de nube:
cat > ssh/sshd_config << 'EOF' Include /etc/ssh/sshd_config.d/*.conf #PermitRootLogin prohibit-password PermitRootLogin no PasswordAuthentication no #PubkeyAuthentication yes X11Forwarding yes PermitEmptyPasswords no EOF echo 'PasswordAuthentication yes' > ssh/sshd_config.d/50-cloud-init.conf -
Muestre solo las directivas activas de
ssh/sshd_config. Compruebe que la líneaPasswordAuthentication, que está sangrada con espacios, aparece en el resultado aunque no comience en la primera columna. -
Busque
PasswordAuthenticationen todos los ficheros dessh/de forma recursiva e indicando el fichero de cada coincidencia. Teniendo en cuenta la regla del primer valor leído y la posición de la directivaInclude, determine qué valor aplicaría el servicio. -
Compruebe en su propio sistema la configuración efectiva de
sshdparapermitrootlogin,passwordauthenticationypermitemptypasswords. Si el servidor SSH no está instalado, instálelo consudo apt install openssh-server. -
Genere una clave de prueba en
tmp/y localícela con la búsqueda recursiva de claves privadas, limitada al directorio del laboratorio.ssh-keygen -q -t ed25519 -N '' -C 'clave de laboratorio' -f tmp/id_prueba
6.4. Ejercicio 4. Análisis forense de registros
Realice los siguientes pasos:
-
Cree el registro de acceso web de muestra
logs/access.log:cat > logs/access.log << 'EOF' 192.0.2.10 - - [18/Oct/2026:08:10:01 +0200] "GET /index.html HTTP/1.1" 200 5120 "-" "Mozilla/5.0" 203.0.113.77 - - [18/Oct/2026:08:10:05 +0200] "GET /../../etc/passwd HTTP/1.1" 400 157 "-" "curl/8.5.0" 203.0.113.77 - - [18/Oct/2026:08:10:06 +0200] "GET /static/%2e%2e/%2e%2e/etc/shadow HTTP/1.1" 404 153 "-" "curl/8.5.0" 198.51.100.99 - - [18/Oct/2026:08:11:00 +0200] "GET /.env HTTP/1.1" 404 153 "-" "Mozilla/5.0 zgrab/0.x" 198.51.100.99 - - [18/Oct/2026:08:11:01 +0200] "GET /.git/config HTTP/1.1" 404 153 "-" "Mozilla/5.0 zgrab/0.x" 198.51.100.99 - - [18/Oct/2026:08:11:02 +0200] "GET /wp-login.php HTTP/1.1" 404 153 "-" "Mozilla/5.0 zgrab/0.x" 192.0.2.55 - - [18/Oct/2026:08:12:00 +0200] "GET /buscar?q=1%27%20OR%20%271%27=%271 HTTP/1.1" 200 812 "-" "sqlmap/1.8" EOF -
Extraiga de
logs/auth.loglas direcciones IP de origen de los intentos fallidos con un patrón ERE y, después, con PCRE y\K. -
Extraiga los nombres de usuario inexistentes que se han intentado utilizar.
-
Comprima una copia del registro con
gzip -k logs/auth.logy busque en ambos ficheros a la vez los accesos aceptados, ocultando el nombre del fichero. -
Detecte en
logs/access.loglos intentos de recorrido de directorios, incluida la variante codificada, y las peticiones de herramientas automatizadas. Indique cuál de las peticiones requiere investigación prioritaria y por qué.
6.5. Ejercicio 5. Script de comprobación de controles
Desarrolle el script ~/lab_filtrado/grep/auditoria_grep.sh, que recibe como argumento el directorio del laboratorio y muestra CONFORME o NO CONFORME para cada uno de estos controles:
-
No existe ninguna cuenta distinta de
rootcon UID 0 enpasswd. -
ssh/sshd_configcontienePermitRootLogin nocomo directiva activa. -
Ningún fichero de
ssh/sshd_config.d/activaPasswordAuthentication yes. -
No existe ninguna clave privada bajo
tmp/.
El script debe usar exclusivamente grep -q y códigos de salida en las condiciones, y debe tratar el código 2 como resultado indeterminado.
6.6. Ejercicio 6. Limpieza del entorno
Realice los siguientes pasos:
-
Elimine el directorio del laboratorio, que incluye la clave privada de prueba, y compruebe que no queda ningún resto.
-
Si instaló
openssh-serversolo para el ejercicio 3, desinstálelo consudo apt purge openssh-server.
7. Recursos y referencias
-
GNU Grep Manual: Documentación oficial de las opciones, los dialectos de expresiones regulares y el rendimiento de GNU
grep.
https://www.gnu.org/software/grep/manual/ -
POSIX.1-2024, capítulo 9, Regular Expressions: Definición normativa de BRE y ERE y de las clases de caracteres.
https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap09.html -
Regex101: Depurador interactivo que explica paso a paso cómo se evalúa un patrón en PCRE y otros motores.
https://regex101.com/ -
Regular-Expressions.info: Referencia exhaustiva sobre el funcionamiento interno de los motores de expresiones regulares y las diferencias entre dialectos.
https://www.regular-expressions.info/ -
MITRE ATT&CK T1552.004, Unsecured Credentials: Private Keys:
https://attack.mitre.org/techniques/T1552/004/ -
Páginas de manual del sistema:
man grep,man 7 regex,man sshd_configyman journalctl.
8. Licencia
Licencia CC BY-NC-ND 4.0
Esta página forma parte del curso Bastionado de Redes y Sistemas © 2026 de José Juan Sánchez Hernández y su contenido se distribuye bajo una licencia Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International.
Esta licencia exige que quienes reutilicen el material otorguen el debido crédito al autor. Permite copiar y redistribuir el material en cualquier medio o formato, únicamente en su forma original, y solo para fines no comerciales.