La primera ejecución de Lynis en un VPS recién creado suele dar algo alrededor de 60 y una larga lista de sugerencias en la que no se sabe por dónde empezar. La buena noticia: 80 u 85 es el trabajo de una tarde, y la mayoría de los pasos no son cosméticos sino realmente útiles. La mala: los últimos quince puntos son inalcanzables en una máquina virtual alquilada, y perseguirlos es un error.

Qué muestra el índice y qué no

El índice de fortificación es la proporción ponderada de pruebas superadas sobre el total, no un porcentaje de seguridad. Lynis ejecuta unas trescientas pruebas y produce dos listas distintas: warnings, que parecen problemas reales, y suggestions, es decir, lo que podría mejorarse. Empiece siempre por los avisos; suelen ser pocos.

Cien puntos no existen: algunas recomendaciones suponen decisiones tomadas al instalar el sistema (particiones separadas para /home, /tmp y /var), otras requieren acceso al gestor de arranque del que un VPS no dispone, y otras se contradicen entre sí. Y comparar el índice propio con el ajeno no sirve de nada: Lynis descuenta puntos por lo que funciona en la máquina. Cada servicio en marcha es un puerto abierto más, una configuración propia y una docena de sugerencias nuevas, por eso los valores altos se ven sobre todo donde no corre nada salvo SSH. Para un servidor de trabajo con sitio, base de datos y correo, 85 es un buen resultado.

Ejecutar como root

sudo lynis audit system

Sin sudo, Lynis se salta todas las pruebas que necesitan archivos del sistema y comunica un índice más bajo, no porque el servidor sea malo, sino porque las comprobaciones no se vieron. El informe se escribe en /var/log/lynis-report.dat y el registro legible en /var/log/lynis.log.

Cada línea de salida empieza con un identificador de prueba como SSH-7408 o KRNL-6000. Por ese identificador se encuentra tanto la explicación como la forma de desactivar una prueba: recuerde su forma, todo lo demás gira en torno a ella.

Lo que de verdad mueve el número

SSH (SSH-7408). El bloque de mayor peso: una sola prueba revisa una docena de parámetros a la vez. No edite todo el sshd_config, deje un archivo aparte para que una actualización del paquete no borre su trabajo:

sudo tee /etc/ssh/sshd_config.d/10-hardening.conf <<'EOF'
PermitRootLogin no
PasswordAuthentication no
MaxAuthTries 3
MaxSessions 2
X11Forwarding no
AllowTcpForwarding no
ClientAliveInterval 300
ClientAliveCountMax 2
LogLevel VERBOSE
TCPKeepAlive no
EOF
sudo sshd -t && sudo systemctl reload ssh

sshd -t antes de recargar el servicio es obligatorio: un error en la configuración con la sesión abierta lo dejará fuera. Y antes de poner PasswordAuthentication no, asegúrese de que la clave funciona de verdad, desde una segunda terminal abierta.

Parámetros del núcleo (KRNL-6000). La prueba revisa unas dos docenas de valores de sysctl. Un archivo para ellos:

sudo tee /etc/sysctl.d/99-hardening.conf <<'EOF'
kernel.dmesg_restrict = 1
kernel.kptr_restrict = 2
kernel.sysrq = 0
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.all.log_martians = 1
EOF
sudo sysctl --system

Herramientas ausentes. Buena parte de las sugerencias se reduce a «instale lo que no está»: auditd (registro de eventos del sistema), aide (integridad de archivos), debsums (integridad de paquetes), unattended-upgrades (actualizaciones de seguridad automáticas), sysstat y acct (contabilidad de procesos), un antivirus. Cada una cierra una o dos recomendaciones, pero instálelas no por los puntos: sin ellas no reconstruirá nada tras un incidente.

Detalles con buena relación esfuerzo/resultado. umask 027 en /etc/login.defs; la caducidad de contraseñas en el mismo archivo; los avisos de /etc/issue y /etc/issue.net; los compiladores legibles solo por root (chmod 700 /usr/bin/gcc). Sobre los avisos, con franqueza: no aportan nada a la seguridad, son una formalidad legal, pero dan un punto.

Una trampa en login.defs

Modificar umask mediante una sustitución de línea con sed deja a menudo varias líneas UMASK en el archivo. Lynis entonces no cuenta el valor, y la prueba AUTH-9328 sigue en rojo aunque el ajuste parezca hecho. Compruebe tras editar:

grep -c '^UMASK' /etc/login.defs

Debe haber exactamente una. Lo mismo vale para cualquier otro parámetro de ese archivo.

Falsos positivos y cómo silenciarlos bien

Algunos avisos no afectan en absoluto a su servidor. Un ejemplo real: en el VPS de un gran proveedor, la prueba PKGS-7388 informa de que no se ha encontrado repositorio de seguridad, sencillamente porque los repositorios están descritos en formato deb822 con una referencia a un archivo de réplicas, mientras Lynis busca la línea habitual. Las actualizaciones de seguridad, en cambio, llegan perfectamente.

Eso se silencia no borrando líneas del informe, sino con un perfil. Los archivos de perfil llevan la extensión .prf (no .prof: ahí se pierde media hora con facilidad), y sus reglas van a /etc/lynis/custom.prf:

skip-test=PKGS-7388
skip-test=KRNL-5788

Una regla: junto a cada línea debe haber un comentario que explique por qué se omite la prueba. Dentro de medio año no recordará si se desactivó porque no se aplica o porque arreglarla daba pereza, y la diferencia entre esos dos casos es todo el asunto.

Lo que no hay que hacer

No persiga la cifra. El índice se infla con facilidad desactivando las pruebas incómodas, y por encima de cierto nivel ese es el único camino, solo que el servidor no se vuelve más seguro por ello. Otra cosa sí es útil: fijar el valor propio y vigilar sus variaciones. Un índice que cae tras una actualización o tras un cambio de configuración hecho por otro es una señal mucho más valiosa que su magnitud absoluta.

Precisamente por eso conviene ejecutar Lynis de forma programada y no una sola vez, y conservar los informes para tener con qué comparar. Cómo se ve todo reunido en una página lo muestra la demostración de abajo: el índice, la lista de avisos con sus identificadores de prueba y lo que ha cambiado desde la ejecución anterior.