LINAUDIT(1) Comandos de usuario User commands LINAUDIT(1)
alexia@lexiworks:~/linaudit

Nombre

Name

linaudit(1)

Auditoría de seguridad de solo lectura para Linux, con un puntaje de 1 a 10. Mira tu máquina como lo haría un atacante o un auditor, y te dice en palabras simples qué está mal, qué tan grave es y cómo arreglarlo.

A read-only security audit for Linux, with a score from 1 to 10. It looks at your machine the way an attacker or an auditor would, and tells you in plain words what is wrong, how serious it is, and how to fix it.

128 controleschecks 9 categoríascategories Debian · Ubuntu · RHEL Rust 1.85+ AGPL-3.0+ es · en
root@gentoocito:~# linaudit
Pantalla de resumen de linaudit: puntaje 6 de 10, hallazgos abiertos por gravedad, estado de cada categoría y la lista de lo más urgente.

Sinopsis

Synopsis

# linaudit [--profile server|desktop|container] [--plain | --json] [--fast]
           [--category LISTALIST] [--min-score N] [--output ARCHIVOFILE] [--lang es|en]

Descripción

Description

linaudit es un chequeo de salud de seguridad para servidores y computadoras Linux. Corre más de cien controles sobre cuentas, SSH, permisos, credenciales expuestas, red, actualizaciones, persistencia y aplicaciones de servidor, y resume todo en un número de 1 a 10 fácil de comparar entre máquinas. Cada hallazgo viene con el comando o la configuración exacta que lo arregla.

linaudit is a security health check for Linux servers and computers. It runs more than a hundred checks over accounts, SSH, permissions, exposed credentials, network, updates, persistence and server applications, and sums everything up in a single number from 1 to 10 that is easy to compare between machines. Every finding comes with the exact command or setting that fixes it.

solo lectura
read-only

Nunca modifica nada del sistema. Cuando encuentra una contraseña o una clave, te dice dónde está, nunca su valor.

It never changes anything on the system. When it finds a password or a key, it tells you where it is, never its value.

puntaje honesto
honest score

Ponderado por gravedad y con techos: con un hallazgo crítico abierto, no hay forma de sacar más de 6.

Weighted by severity and capped: with one open critical finding there is no way to score above 6.

interfaz de terminal
terminal UI

Resumen, hallazgos filtrables y categorías. Buscás, filtrás y copiás el arreglo con y.

Summary, filterable findings and categories. Search, filter, and copy the fix with y.

texto y JSON
text and JSON

Reporte plano para leer o mandar por mail, y JSON para scripts, cron, CI o un colector central.

Plain report to read or email, and JSON for scripts, cron, CI or a central collector.

perfiles
profiles

Servidor, escritorio o contenedor: el criterio se adapta a lo que es la máquina, y lo deja escrito.

Server, desktop or container: the criteria adapt to what the machine is, and the report says so.

castellano e inglés
Spanish and English

Traducciones con gettext, embebidas en el binario. Sumar un idioma es un archivo .po y unas líneas de código.

gettext translations embedded in the binary. Adding a language is one .po file and a few lines of code.

Capturas

Screenshots

Un recorrido rápido: la bienvenida, la auditoría en curso y el resumen final.

A quick tour: the welcome screen, the audit in progress, and the final summary.

bienvenida
Pantalla de bienvenida de linaudit con el logo, los datos del sistema y el selector de idioma.
Bienvenida. Datos del sistema, aviso si no sos root y, la primera vez, la elección de idioma.
Welcome. System details, a warning if you are not root and, the first time, the language choice.
auditando
linaudit auditando el sistema: barra de progreso y lista de las nueve categorías.
Auditoría. Las nueve categorías, una por una. Con --fast tarda segundos.
Audit. The nine categories, one by one. With --fast it takes seconds.

Al terminar hay tres pestañas: Resumen (el puntaje, los hallazgos abiertos por gravedad y los más urgentes, como en la captura de arriba), Hallazgos (cada problema con su detalle y su arreglo) y Categorías. Con ? ves los atajos y con q salís.

When it finishes there are three tabs: Summary (the score, open findings by severity and the most urgent ones, as in the screenshot above), Findings (every problem with its details and its fix) and Categories. Press ? for the shortcuts and q to quit.

Qué revisa

What it checks

accounts12 Cuentas con UID 0, contraseñas vacías o con hashes débiles, NOPASSWD en sudo, cuentas de servicio con shell. UID 0 accounts, empty or weakly hashed passwords, NOPASSWD in sudo, service accounts with a shell.
ssh16 Configuración efectiva de OpenSSH: login de root, contraseñas, algoritmos débiles, bloques Match, claves de host. Effective OpenSSH configuration: root login, passwords, weak algorithms, Match blocks, host keys.
filesystem18 Permisos críticos, SUID/SGID fuera de paquetes o en binarios de GTFOBins, world-writable, montajes de /tmp. Critical permissions, SUID/SGID outside packages or on GTFOBins binaries, world-writable files, /tmp mounts.
secrets8 Credenciales en texto plano, en URLs, historiales, units de systemd y cron; claves privadas legibles por todos. Plaintext credentials, in URLs, shell histories, systemd units and cron; world-readable private keys.
network17 Firewall local, puertos expuestos y parámetros de red del kernel. Local firewall, exposed ports and kernel network parameters.
patching7 Actualizaciones pendientes, reinicio pendiente, fin de soporte de la distribución. Pending updates, pending reboot, end of support of the distribution.
persistence15 Indicadores de compromiso y mecanismos de persistencia: PAM, ld.so.preload, cron, units, claves autorizadas. Signs of compromise and persistence mechanisms: PAM, ld.so.preload, cron, units, authorized keys.
hardening17 SELinux/AppArmor, auditd, sincronización horaria, logs, parámetros de endurecimiento del kernel. SELinux/AppArmor, auditd, time sync, logging, kernel hardening parameters.
apps18 Tomcat, Redis, Docker, PostgreSQL, Samba, Apache y nginx: las configuraciones peligrosas de siempre. Tomcat, Redis, Docker, PostgreSQL, Samba, Apache and nginx: the usual dangerous settings.

Cada control tiene un ID estable (SSH-001, FS-013…) que nunca cambia de significado. La lista completa, con la gravedad de cada uno, está en docs/CHECKS.md.

Every check has a stable ID (SSH-001, FS-013…) that never changes meaning. The full list, with each one's severity, is in docs/CHECKS.md.

Instalación

Install

Debian y derivadas

Debian and derivatives

El paquete está en camino al archivo oficial de Debian:

The package is on its way into the official Debian archive:

$ sudo apt install linaudit

Desde el código fuente

From source

Hace falta Rust 1.85 o más nuevo (la versión de Debian 13). Funciona en cualquier distribución; no tiene dependencias en tiempo de ejecución.

You need Rust 1.85 or newer (the version in Debian 13). It works on any distribution and has no runtime dependencies.

$ git clone https://github.com/alexiarstein/linaudit
$ cd linaudit
$ cargo build --release
$ sudo install -m 755 target/release/linaudit /usr/local/bin/

Primer uso

First run

$ sudo linaudit
Correlo con sudo. Sin root muchos controles no pueden leer lo que necesitan (la base de contraseñas, las reglas del firewall). linaudit igual corre, pero avisa qué no pudo evaluar y el puntaje no puede pasar de 6: lo que no se pudo mirar nunca cuenta como bien.
Run it with sudo. Without root many checks cannot read what they need (the password database, the firewall rules). linaudit still runs, but it tells you what it could not evaluate and the score cannot go above 6: whatever could not be looked at never counts as fine.

Opciones

Options

--plain
Reporte de texto en vez de la interfaz interactiva. Con --all incluye también los controles aprobados.
Text report instead of the interactive interface. With --all it also lists the checks that passed.
--json
Salida JSON, pensada para un colector central o para procesar con jq.
JSON output, meant for a central collector or for processing with jq.
--output ARCHIVO
Guarda el reporte en el archivo (con modo 600) en vez de imprimirlo.
Saves the report to the file (mode 600) instead of printing it.
--fast
Saltea los barridos completos del disco (SUID, world-writable…): segundos en vez de minutos.
Skips the full disk sweeps (SUID, world-writable…): seconds instead of minutes.
--category ssh,accounts
Corre solo algunas categorías. --list-categories las muestra.
Runs only some categories. --list-categories lists them.
--profile PERFIL
server, desktop, container o auto. Evita la pregunta inicial. También LINAUDIT_PROFILE.
server, desktop, container or auto. Skips the initial question. Also LINAUDIT_PROFILE.
--min-score N
Código de salida 1 si el puntaje es menor que N. Útil en cron, CI y monitoreo.
Exit code 1 if the score is lower than N. Handy in cron, CI and monitoring.
--waivers ARCHIVO
Archivo de excepciones extra, además de /etc/linaudit/waivers.conf.
Extra waivers file, besides /etc/linaudit/waivers.conf.
--lang es|en
Idioma para esta corrida. También LINAUDIT_LANG.
Language for this run. Also LINAUDIT_LANG.
--no-color
Sin colores (también respeta NO_COLOR).
No colors (NO_COLOR is honored too).
# auditoría rápida de un servidor, sin preguntas, guardada en JSONquick server audit, no questions, saved as JSON
$ sudo linaudit --profile server --fast --json --output reporte.json

# en un pipeline: falla si el puntaje baja de 7in a pipeline: fail if the score drops below 7
$ sudo linaudit --plain --min-score 7

Todas las opciones están en linaudit --help y en man linaudit.

Every option is in linaudit --help and man linaudit.

Perfiles

Profiles

No todos los controles tienen sentido en todas las máquinas: un banner legal importa en un servidor corporativo, no en tu notebook; el firewall de un contenedor lo maneja su host. linaudit detecta el perfil que corresponde y te lo sugiere.

Not every check makes sense on every machine: a legal banner matters on a corporate server, not on your laptop; a container's firewall is handled by its host. linaudit detects the right profile and suggests it.

PerfilProfile ParaFor Qué cambiaWhat changes
server servidores, VPS, todo lo expuestoservers, VPS, anything exposed nada: todos los controles con su gravedad completanothing: every check at full severity
desktop computadoras personalespersonal computers relaja los controles de servidor corporativo; el firewall baja de ALTO a MEDIOrelaxes corporate-server checks; the firewall goes from HIGH to MEDIUM
container contenedores y VMs efímerascontainers and ephemeral VMs lo que maneja el host (reloj, firewall, kernel, logs) queda como "no aplica"what the host handles (clock, firewall, kernel, logs) becomes "not applicable"

Un perfil nunca esconde un control: solo le cambia la gravedad o lo marca como "no aplica", y lo deja escrito en el reporte.

A profile never hides a check: it only changes its severity or marks it "not applicable", and says so in the report.

Cómo se calcula el puntaje

How the score works

Cada control pesa según su gravedad. Los aprobados suman su peso, las advertencias la mitad y las fallas nada; el porcentaje resultante se lleva a una escala de 1 a 10.

Each check weighs according to its severity. Passed checks add their weight, warnings half of it, and failures nothing; the resulting percentage is mapped onto a 1 to 10 scale.

CRÍTICOCRITICAL10
ALTOHIGH6
MEDIOMEDIUM3
BAJOLOW1
INFO0

Después se aplican techos, porque un "9 de 10" con un agujero crítico abierto sería mentira:

Then caps are applied, because a "9 out of 10" with an open critical hole would be a lie:

Si queda abiertoIf still open MáximoMaximum
1 crítico1 critical6
2 críticos2 critical4
3 o más críticos3+ critical3
5 o más altos5+ high6
1 a 4 altos1–4 high8
menos del 90 % evaluadounder 90 % evaluated6

El reporte siempre dice qué techo bajó el puntaje y por qué, así sabés qué arreglar primero.

The report always says which cap lowered the score and why, so you know what to fix first.

Excepciones y auditorías periódicas

Waivers and scheduled audits

Aceptar un hallazgo a propósito

Accepting a finding on purpose

A veces un hallazgo es una decisión tomada: por ejemplo, la máquina está detrás de un firewall dedicado. Anotalo en /etc/linaudit/waivers.conf, una línea por control, con el motivo:

Sometimes a finding is a deliberate decision: for example, the machine sits behind a dedicated firewall. Write it down in /etc/linaudit/waivers.conf, one line per check, with the reason:

NET-001   # Firewall perimetral dedicado. Ticket INF-1234Dedicated perimeter firewall. Ticket INF-1234

El control deja de afectar el puntaje, pero sigue apareciendo en el reporte con su motivo: la decisión queda a la vista.

The check stops affecting the score but still shows up in the report with its reason: the decision stays visible.

Una auditoría por semana

A weekly audit

El paquete de Debian trae un timer de systemd (apagado por defecto) que corre la auditoría una vez por semana y guarda el último reporte en /var/lib/linaudit/latest.json, con permisos restringidos.

The Debian package ships a systemd timer (disabled by default) that runs the audit once a week and keeps the latest report in /var/lib/linaudit/latest.json, with restricted permissions.

$ sudo systemctl enable --now linaudit.timer

Compilar y probar

Building and testing

linaudit está escrito en Rust y es un workspace de Cargo con dos crates: el motor, sin interfaz, y el binario. Hace falta Rust 1.85 o más nuevo.

linaudit is written in Rust as a Cargo workspace with two crates: the engine, with no user interface, and the binary. You need Rust 1.85 or newer.

$ cargo build --release     # binario en target/release/linauditbinary in target/release/linaudit
$ cargo test                # unitarios, fixtures de disco, render de la TUI, traduccionesunit tests, filesystem fixtures, TUI rendering, translations
$ ./target/release/linaudit --fast --plain
crates/linaudit-core   motor: controles, perfiles, excepciones, puntaje e i18nengine: checks, profiles, waivers, score and i18n
crates/linaudit        binario: CLI, interfaz (ratatui), reportes de texto y JSONbinary: CLI, interface (ratatui), text and JSON reports
po/                    traducciones (gettext)translations (gettext)
doc/                   páginas de manualman pages
etc/                   archivos por defecto de /etc/linauditdefault /etc/linaudit files
contrib/               units de systemd y scripts de mantenimientosystemd units and maintenance scripts
debian/                empaquetado para DebianDebian packaging

Armar el paquete .deb

Building the .deb

El directorio debian/ compila contra los crates de Rust empaquetados en Debian (librust-*-dev) con el wrapper de cargo de Debian, sin bajar nada de crates.io. Además genera los autocompletados de bash, zsh y fish.

The debian/ directory builds against the Rust crates packaged in Debian (librust-*-dev) with Debian's cargo wrapper, without downloading anything from crates.io. It also generates bash, zsh and fish completions.

$ sudo apt build-dep .
$ dpkg-buildpackage -us -uc -b
$ sudo apt install ../linaudit_*.deb

El código compila con las versiones de crates de Debian 13 (ratatui 0.29, toml 0.8) y de unstable (ratatui 0.30, toml 1.x). Si actualizás dependencias, mantené las dos funcionando.

The code builds with the crate versions in Debian 13 (ratatui 0.29, toml 0.8) and in unstable (ratatui 0.30, toml 1.x). If you update dependencies, keep both working.

Traducir linaudit a otro idioma

Translating linaudit

Los textos del código están en inglés y son las claves (msgid) de los catálogos gettext de po/. Los catálogos van embebidos en el binario, así que funciona igual instalado desde el .deb que suelto. Si falta una traducción, se muestra el inglés.

The texts in the code are in English and are the keys (msgid) of the gettext catalogs in po/. The catalogs are embedded in the binary, so it works the same installed from the .deb or as a loose binary. If a translation is missing, the English text is shown.

Para sumar un idioma (en el ejemplo, portugués, pt):

To add a language (in this example, Portuguese, pt):

  1. Crear el catálogo a partir de la plantilla. Hacen falta las herramientas de gettext (apt install gettext).

    Create the catalog from the template. You need the gettext tools (apt install gettext).

    $ msginit -i po/linaudit.pot -o po/pt.po -l pt --no-translator

    Revisá que el encabezado tenga bien el Plural-Forms del idioma.

    Check that the header has the right Plural-Forms for the language.

  2. Traducir con Poedit, Lokalize o cualquier editor. Los valores van por nombre: {n}, {dir}… y la traducción tiene que conservar exactamente los mismos {nombres}. Los IDs de los controles, las claves del JSON y los valores de la CLI no se traducen.

    Translate with Poedit, Lokalize or any editor. Values are inserted by name: {n}, {dir}… and the translation must keep exactly the same {names}. Check IDs, JSON keys and CLI values are not translated.

    msgid "Found {n} files in {dir}"
    msgstr "Encontrados {n} arquivos em {dir}"
  3. Registrar el idioma en crates/linaudit-core/src/i18n.rs: agregalo al enum Lang y a Lang::ALL, completá code(), native_name(), from_code(), catalog() y plural_index(), sumá su constante en set_lang()/lang(), y embebé el catálogo:

    Register the language in crates/linaudit-core/src/i18n.rs: add it to the Lang enum and to Lang::ALL, fill in code(), native_name(), from_code(), catalog() and plural_index(), add its constant to set_lang()/lang(), and embed the catalog:

    static PT: LazyLock<Catalog> =
        LazyLock::new(|| Catalog::parse(include_str!("../../../po/pt.po")));

    El compilador te va a marcar cada match que falte cubrir.

    The compiler will point out every match left to cover.

  4. Verificar y probar.

    Check and try it.

    $ msgfmt --check-format --statistics -o /dev/null po/pt.po
    $ cargo test
    $ cargo run --release -- --lang pt --fast

    Opcional pero muy bienvenido: una página de manual traducida (doc/linaudit.pt.1) y un README.pt.md.

    Optional but very welcome: a translated man page (doc/linaudit.pt.1) and a README.pt.md.

Mantener las traducciones al día

Keeping translations up to date

Cuando cambian los textos del código, este script regenera po/linaudit.pot y actualiza todos los po/*.po: los textos nuevos quedan sin traducir y los que ya no existen, como obsoletos.

When the texts in the code change, this script regenerates po/linaudit.pot and updates every po/*.po: new texts are left untranslated and removed ones are marked obsolete.

$ contrib/i18n-update.sh

En el código, todo texto visible pasa por tr!("..."); los plurales, por trn!. Un test falla si algún texto del código no está en po/es.po.

In the code, every user-facing text goes through tr!("..."); plurals go through trn!. A test fails if any text in the code is missing from po/es.po.

tr!("{n} files", n = count)
trn!("{n} file", "{n} files", count, n = count)

Colaborar

Contributing

La regla de oro: linaudit es de solo lectura. Ningún control puede modificar el sistema, y ninguna salida puede contener el valor de un secreto (solo el archivo y la línea donde se encontró). Un pull request que rompa esto no se acepta.
The golden rule: linaudit is read-only. No check may modify the system, and no output may contain the value of a secret (only the file and line where it was found). Pull requests that break this will not be merged.

Agregar un control

Adding a check

Los controles viven en crates/linaudit-core/src/checks/, un módulo por categoría. Cada uno tiene un ID estable que no cambia de significado nunca, porque de él dependen las excepciones y los colectores. Sumá el ID nuevo a docs/CHECKS.md y cubrilo con un test usando el fixture de sistema de archivos (checks/fixture.rs), que permite probarlo sin root.

Checks live in crates/linaudit-core/src/checks/, one module per category. Each has a stable ID that never changes meaning, because waivers and collectors depend on it. Add the new ID to docs/CHECKS.md and cover it with a test using the filesystem fixture (checks/fixture.rs), which lets you test it without root.

También suma

Also welcome

  • Reportes de falsos positivos (sobre todo en la búsqueda de credenciales).
  • False-positive reports (especially in the credentials search).
  • Pruebas en la familia Red Hat (RHEL, Rocky, Alma, Fedora), que está menos probada que Debian.
  • Testing on the Red Hat family (RHEL, Rocky, Alma, Fedora), which is less tested than Debian.
  • Traducciones y mejoras al empaquetado.
  • Translations and packaging fixes.

Advertencias

Caveats

  • Los reportes describen los puntos débiles de la máquina: guardalos en privado.
  • Reports describe the machine's weak spots: keep them private.
  • Algunos controles son heurísticos y pueden dar falsos positivos. Tomá los hallazgos como cosas para revisar, no como veredictos.
  • Some checks are heuristic and can produce false positives. Treat findings as things to review, not verdicts.
  • No reemplaza una auditoría formal de cumplimiento (CIS, STIG), un análisis forense ni un antivirus/EDR. Es un chequeo de salud rápido y honesto que podés correr todas las veces que quieras.
  • It does not replace a formal compliance audit (CIS, STIG), forensic analysis or an antivirus/EDR. It is a quick, honest health check you can run as often as you like.

Véase también

See also