Ghost AcademyGhostLinux · Ghost Academy
GhostLinuxMódulo 110Examen 102-500

Seguridad

LPI 110.1 Tareas de seguridadLPI 110.2 Seguridad del hostLPI 110.3 Cifrado de datos

Último módulo del curso. LPIC-1 no es una certificación de seguridad ofensiva — no esperes nada parecido a GhostOffensive aquí — pero sí exige que un administrador de sistemas sepa las tareas mínimas de higiene de seguridad que le corresponden: quién puede hacer qué, qué servicios están expuestos, y cómo proteger una conexión y unos datos con cifrado real.

Objetivos de la unidad

1. LPI 110.1 — Tareas de administración de seguridad

1.1 Buscar lo que no debería estar ahí

root@lpic1:~#
$ find / -perm -4000 -type f 2>/dev/null
/usr/bin/passwd
/usr/bin/sudo
/usr/bin/su
Ya viste find -perm -4000 (binarios SUID) en el módulo 104 — aquí es donde ese comando se convierte en una tarea de seguridad real: auditar esa lista periódicamente y preguntarte si cada binario SUID de la lista tiene que estar ahí. Un SUID nuevo que no reconoces, en una ruta rara, es la señal clásica de que algo se ha instalado sin tu conocimiento.
root@lpic1:~#
$ awk -F: '($2=="") {print $1}' /etc/shadow

Ese awk busca cuentas con el campo de contraseña vacío en /etc/shadow — es decir, cuentas sin contraseña que permitirían entrar sin credenciales. En un sistema sano, no debería devolver nada.

root@lpic1:~#
$ grep -v nologin /etc/passwd | grep -v '/bin/false'
root:x:0:0:root:/root:/bin/bash
jose:x:1001:1001:Jose Perez:/home/jose:/bin/bash

Útil para ver rápidamente qué cuentas pueden iniciar sesión de verdad, descartando las cuentas de servicio que ya bloqueaste con /usr/sbin/nologin en el módulo 107.

1.2 Límites de recursos por usuario

root@lpic1:~#
$ ulimit -a
core file size          (blocks, -c) 0
open files                      (-n) 1024
max user processes               (-u) 15938
stack size              (Kbytes, -s) 8192

ulimit fija límites para la sesión actual; para que persistan por usuario/grupo se configuran en /etc/security/limits.conf (parte de PAM, que ya trabaja por debajo de login/sudo/SSH sin que lo veas directamente):

root@lpic1:~#
$ cat /etc/security/limits.conf | grep -v '^#' | grep .
jose    hard    nproc    100
jose    soft    nofile   2048
@desarrollo hard   core     0
CampoSignificado
DominioUsuario, @grupo, o * (todos)
soft / hardLímite blando (el usuario puede subirlo hasta el límite duro) / límite duro (techo absoluto)
Tiponproc (procesos máximos), nofile (ficheros abiertos), core (tamaño de volcados de memoria)...
Un límite bajo de nproc por usuario es justo lo que evita que una fork bomb o un script descontrolado de un solo usuario se coma todos los procesos disponibles del sistema entero — una tarea de seguridad tan de "administración básica" como suena, y literalmente el objetivo que LPI llama "configurar límites de recursos de usuario".

1.3 Delegar privilegios con sudo, no con contraseñas compartidas de root

root@lpic1:~#
$ visudo
# abre /etc/sudoers con bloqueo y validacion de sintaxis antes de guardar - nunca lo edites con otro editor
root@lpic1:~#
$ cat /etc/sudoers.d/jose
jose ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx
¿Por qué visudo y no nano /etc/sudoers? Si guardas una sintaxis rota en /etc/sudoers con un editor normal, puedes dejar a todo el mundo, incluido root, sin poder usar sudo nunca más. visudo valida la sintaxis antes de escribir el fichero de verdad, y si detecta un error te da la opción de corregirlo sin aplicar el cambio roto.

La línea del ejemplo le da a jose permiso para reiniciar solo ese servicio concreto, sin pedir contraseña (NOPASSWD) — el principio de mínimo privilegio en la práctica: nunca ALL=(ALL) ALL si con un permiso más estrecho basta.

2. LPI 110.2 — Configurar la seguridad del host

2.1 Reducir la superficie de ataque: apagar lo que no usas

root@lpic1:~#
$ systemctl list-units --type=service --state=running
UNIT              LOAD   ACTIVE SUB     DESCRIPTION
ssh.service       loaded active running OpenBSD Secure Shell server
cups.service      loaded active running CUPS Scheduler
bluetooth.service loaded active running Bluetooth service
root@lpic1:~#
$ systemctl disable --now bluetooth
# lo para ahora mismo y evita que vuelva a arrancar en el proximo reinicio
Ya viste systemctl disable y mask en el módulo 101 desde el punto de vista de arranque — aquí es la misma herramienta aplicada como tarea de seguridad: todo servicio en escucha que no necesitas es una puerta más que alguien podría intentar forzar. mask va un paso más allá que disable: impide incluso que otro servicio lo arranque como dependencia.

2.2 TCP Wrappers: /etc/hosts.allow y /etc/hosts.deny

Un mecanismo antiguo pero que el examen todavía pregunta, para servicios compilados con soporte libwrap:

root@lpic1:~#
$ cat /etc/hosts.deny
ALL: ALL
root@lpic1:~#
$ cat /etc/hosts.allow
sshd: 192.168.1.0/24
sshd: 10.0.0.5
Orden de evaluación fijo y siempre el mismo: primero se consulta /etc/hosts.allow — si hay coincidencia, se permite y se para ahí. Si no hay coincidencia, se consulta /etc/hosts.deny — si hay coincidencia ahí, se deniega. Si no coincide en ninguno de los dos, se permite por defecto. El patrón ALL: ALL en hosts.deny combinado con reglas específicas en hosts.allow (como el ejemplo) es la forma estándar de "denegar todo salvo lo que permito explícitamente".

2.3 Firewall básico: iptables/nftables y ufw

HerramientaNivel
nftablesEl framework de filtrado de paquetes actual en el kernel, sustituto de iptables
iptablesEl framework clásico — en distros modernas, iptables suele ser en realidad una capa de compatibilidad que traduce a nftables por debajo
ufw (Uncomplicated Firewall)Interfaz simplificada sobre iptables/nftables, la que de verdad usa casi todo el mundo en Debian/Ubuntu en el día a día
root@lpic1:~#
$ ufw status verbose
Status: active
Default: deny (incoming), allow (outgoing)
To                         Action      From
22/tcp                     ALLOW       Anywhere
80,443/tcp                 ALLOW       Anywhere
root@lpic1:~#
$ ufw allow 22/tcp
Rule added
root@lpic1:~#
$ ufw deny from 203.0.113.50
Rule added
root@lpic1:~#
$ ufw enable
Firewall is active and enabled on system startup
🧰 Recursos relacionados (Ghost Academy)

Practica más — labs ya publicados en Ghost Academy sobre este tema: 🔥 UFW: firewall (guía)

3. LPI 110.3 — Asegurar datos con cifrado

3.1 SSH: la base de un acceso remoto seguro

El objetivo de examen más denso de todo el módulo. Empieza por la diferencia entre autenticarte con contraseña y con clave:

root@lpic1:~#
$ ssh-keygen -t ed25519 -C "jose@lpic1-lab"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/jose/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Your identification has been saved in /home/jose/.ssh/id_ed25519
Your public key has been saved in /home/jose/.ssh/id_ed25519.pub
FicheroQué es¿Se comparte?
id_ed25519 (o id_rsa)Clave privadaNunca, bajo ningún concepto
id_ed25519.pubClave públicaSí — es la que copias al servidor
~/.ssh/authorized_keys (en el servidor)Lista de claves públicas autorizadas a entrar como ese usuario—
~/.ssh/known_hosts (en el cliente)Huellas de servidores a los que ya te has conectado — detecta si la clave del servidor cambia inesperadamente (posible MITM)—
root@lpic1:~#
$ ssh-copy-id jose@servidor
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'jose@servidor'"
and check to make sure that only the key(s) you wanted were added.
root@lpic1:~#
$ ssh jose@servidor
# ya no pide contraseña: autentica con la clave privada local contra la publica ya copiada
ssh-copy-id no hace magia — simplemente añade el contenido de tu .pub al final de ~/.ssh/authorized_keys en el servidor, por SSH, usando la contraseña una última vez. Puedes hacerlo a mano exactamente igual con cat y redirección si no tienes ssh-copy-id disponible.

3.2 Configuración del servidor SSH

root@lpic1:~#
$ grep -vE '^#|^$' /etc/ssh/sshd_config
Port 22
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
X11Forwarding yes
DirectivaEfecto
PortPuerto en el que escucha sshd — cambiarlo del 22 no es "seguridad" real, solo reduce ruido de escaneos automáticos
PermitRootLogin noObliga a entrar como usuario normal y usar sudo después — práctica estándar recomendada
PasswordAuthentication noDesactiva login por contraseña por completo, solo admite clave — el endurecimiento más efectivo de todos una vez que ya tienes tu clave funcionando
PubkeyAuthentication yesHabilita la autenticación por clave pública (normalmente ya viene activada por defecto)
X11Forwarding yesPermite el reenvío de X11 que viste en el módulo 106 (ssh -X)
Orden obligatorio al endurecer un servidor SSH remoto: primero genera y copia tu clave, confirma que entras con ella sin contraseña, y solo entonces pones PasswordAuthentication no y reinicias sshd. Hacerlo al revés — desactivar contraseña antes de validar la clave — es la forma más clásica de quedarte fuera de tu propio servidor.

3.3 Configuración del lado cliente: ~/.ssh/config

root@lpic1:~#
$ cat ~/.ssh/config
Host servidor-bd
    HostName 192.168.1.20
    User jose
    Port 2222
    IdentityFile ~/.ssh/id_ed25519_bd
root@lpic1:~#
$ ssh servidor-bd
# usa automaticamente el host, usuario, puerto y clave de la entrada de arriba

3.4 GPG: cifrado y firma de datos

GPG (GNU Privacy Guard, implementación libre de OpenPGP) cifra ficheros y correo, y firma digitalmente para demostrar autoría e integridad — con el mismo par de claves pública/privada que ya conoces de SSH, pero para datos en reposo, no para una sesión interactiva.

root@lpic1:~#
$ gpg --full-generate-key
Please select what kind of key you want:
   (1) RSA and RSA
Requested keysize is 3072 bits
Real name: Jose Perez
Email address: jose@ejemplo.com
...
public and secret key created and signed.
root@lpic1:~#
$ gpg --list-keys
pub   rsa3072 2026-10-02 [SC]
      A1B2C3D4E5F6...
uid           [ultimate] Jose Perez <jose@ejemplo.com>
ComandoQué hace
gpg --encrypt -r destinatario ficheroCifra un fichero con la clave pública del destinatario — solo su clave privada puede descifrarlo
gpg --decrypt fichero.gpgDescifra con tu propia clave privada
gpg --sign ficheroFirma con tu clave privada — cualquiera con tu clave pública puede verificar que el fichero es tuyo y no se ha modificado
gpg --verify fichero.sigVerifica una firma
gpg --export -a correo > clave.pubExporta tu clave pública en formato texto, para compartirla
gpg --import clave.pubImporta la clave pública de otra persona para poder cifrarle/verificarla
gpg -c ficheroCifrado simétrico con una contraseña compartida, sin pares de claves — más simple, pero hay que compartir la contraseña por un canal aparte
root@lpic1:~#
$ gpg --encrypt -r jose@ejemplo.com informe.pdf
# genera informe.pdf.gpg, cifrado con la clave publica de jose
root@lpic1:~#
$ gpg --decrypt informe.pdf.gpg > informe.pdf
# pide la frase de paso de tu clave privada para descifrar
Diferencia clave que pregunta el examen: cifrado asimétrico (--encrypt -r) usa un par de claves — pública para cifrar, privada para descifrar — y no requiere compartir ningún secreto de antemano. Cifrado simétrico (-c) usa la misma contraseña para cifrar y descifrar, así que esa contraseña sí hay que transmitirla de forma segura a quien deba descifrar.

Práctica guiada

  1. En tu VM: ejecuta find / -perm -4000 -type f 2>/dev/null y revisa que reconoces todos los binarios SUID listados.
  2. Genera un par de claves SSH con ssh-keygen -t ed25519 y cópialas a una segunda VM (o a la misma, por localhost) con ssh-copy-id.
  3. Confirma que entras sin contraseña, y solo entonces pon PasswordAuthentication no en /etc/ssh/sshd_config y reinicia sshd con systemctl restart sshd.
  4. Instala ufw si no lo tienes, activa el firewall con una regla que permita SSH (ufw allow 22/tcp antes de ufw enable, para no quedarte fuera) y revisa ufw status verbose.
  5. Genera un par de claves GPG con gpg --full-generate-key, cifra un fichero de prueba para ti mismo y descífralo.
  6. Añade una entrada a /etc/sudoers.d/ (con visudo -f) que te dé permiso para un único comando concreto sin contraseña, y pruébala.

Resumen de comandos del módulo

BloqueComandos clave
110.1 Tareas de seguridadfind -perm -4000, ulimit, /etc/security/limits.conf, visudo, /etc/sudoers.d/
110.2 Seguridad del hostsystemctl disable/mask, /etc/hosts.allow/.deny, ufw/iptables/nftables
110.3 Cifradossh-keygen, ssh-copy-id, sshd_config, ~/.ssh/config, gpg --encrypt/--decrypt/--sign

Autoevaluación

  1. ¿Qué comando de awk usarías para detectar cuentas con contraseña vacía en /etc/shadow?
  2. ¿Por qué se usa siempre visudo para editar /etc/sudoers en vez de un editor normal?
  3. Explica el orden exacto de evaluación de /etc/hosts.allow y /etc/hosts.deny.
  4. ¿Qué pasos debes seguir, en orden, antes de poner PasswordAuthentication no en un servidor SSH remoto, y por qué ese orden es tan importante?
  5. ¿Qué fichero nunca debes compartir ni copiar a ningún servidor: la clave SSH pública o la privada?
  6. ¿Qué diferencia hay entre cifrado simétrico (gpg -c) y asimétrico (gpg --encrypt -r) en cuanto a qué hay que compartir con quién?

🎓 Fin del curso

Con este módulo se completa el temario íntegro de LPIC-1 (exámenes 101-500 y 102-500): los 11 módulos de GhostLinux, de la instalación del sistema a la seguridad básica. El siguiente paso es la validación: repasa los tests temáticos y el simulador oficial de 250 preguntas en Recursos, y cuando encadenes simulacros por encima del 80% de aciertos de forma consistente, reserva el examen oficial con confianza.

← 109 · RedesÍndice del curso