Mejores prácticas de administración
Resumen
Esta guía de estudio independiente reúne hábitos que reducen el riesgo operativo de un servidor Linux: privilegios mínimos, actualizaciones controladas, configuración reproducible, documentación y evidencia. No es material oficial ni está afiliada a la Linux Foundation. Su valor está en la ejecución constante: una política que nadie verifica no protege nada. Cada cambio debe ser reversible y cada acceso, registrado.
Objetivos de aprendizaje
- Relacionar controles de seguridad con tareas de administración.
- Aplicar mínimo privilegio en cuentas, grupos y servicios.
- Planificar actualizaciones y líneas base.
- Documentar cambios, dependencias y reversión.
- Verificar con registros que la configuración sigue vigente.
- Proteger secretos y endurecer el acceso remoto con configuración comprobable.
Prerrequisitos y conexiones
Necesitas soltura con cuentas, paquetes y unidades de systemd; repásalo en Administración de sistemas. Conecta con Resolución de problemas, porque un registro ordenado acorta el diagnóstico, y con Recuperación ante desastres.
Marcos y priorización de controles
Los marcos no sustituyen el criterio del administrador: ayudan a decidir qué proteger primero. Los CIS Controls agrupan salvaguardas técnicas y organizativas, desde el inventario hasta la respuesta a incidentes, y proponen implantarlas por grupos según riesgo y madurez. El NIST CSF organiza las actividades en Gobernar, Identificar, Proteger, Detectar, Responder y Recuperar. Usarlos no certifica la organización: hay que seleccionar controles y registrar evidencia.
Un inventario confiable es el punto de partida. Sin saber qué servidores existen, qué versiones ejecutan y quién los usa, no se puede parchear ni responder a un incidente. Registra por host nombre, dirección, función, sistema operativo, criticidad, responsable y ventana de mantenimiento. hostnamectl, ip -br address, lsblk y systemctl list-units --type=service aportan datos objetivos. La información debe vivir en un repositorio versionado, no en la memoria.
La priorización considera exposición, impacto y probabilidad: un servicio accesible desde Internet con una vulnerabilidad conocida suele ser más urgente que un equipo de laboratorio aislado. CIS y NIST CSF ofrecen un vocabulario común para justificar esas decisiones.
Identidad, privilegios y acceso
Cada persona debe usar una cuenta nominativa. Compartir root impide atribuir acciones y facilita el uso indebido de una credencial. sudo delega comandos concretos y registra la ejecución; visudo -c valida la sintaxis. sudo -l -U ana muestra qué puede ejecutar una cuenta y getent group sudo revela la pertenencia al grupo administrativo. Revísalos tras cada alta, baja o cambio de rol.
El mínimo privilegio también se aplica a servicios. Un proceso no debe ejecutarse como root si solo lee un directorio o escucha un puerto no privilegiado. Las unidades de systemd admiten NoNewPrivileges=yes, PrivateTmp=yes, ProtectSystem=strict y un CapabilityBoundingSet= reducido. systemd-analyze security nginx.service estima la exposición y sugiere directivas; es una guía, no una garantía.
sudo visudo -c
sudo -l -U ana
getent group sudo
systemd-analyze security nginx.service --no-pager
La autenticación administrativa merece controles adicionales: claves SSH, contraseñas únicas, MFA en el acceso remoto y bloqueo del login directo de root. Antes de recargar SSH, valida con sshd -t; un error de sintaxis puede dejar fuera a todos. Mantén una sesión abierta mientras pruebas el nuevo acceso para poder revertir.
Secretos y credenciales
Las contraseñas de base de datos, las claves de API y los certificados no pertenecen a los repositorios de código. Guárdalos fuera del árbol de fuente, con permisos que solo permitan lectura al servicio —chmod 600 o un grupo dedicado— y rota el valor cuando alguien haya podido ver el histórico: un secreto copiado en un commit sigue vigente aunque el archivo se borre después, porque el historial lo conserva.
systemd admite EnvironmentFile= en las unidades para cargar variables desde un archivo externo que no viaja con el código. systemctl edit nginx crea una sobrescritura en /etc/systemd/system/nginx.service.d/ sin tocar la unidad original, que permanece intacta en /usr/lib/systemd/system; tras cambiar el archivo de entorno, systemctl daemon-reload y un reinicio aplican el valor nuevo. systemctl show nginx -p EnvironmentFiles confirma qué archivo quedó enlazado, y revisar el archivo con permisos restringidos completa la comprobación.
sudo systemctl edit nginx
systemctl show nginx -p EnvironmentFiles
sudo chmod 600 /etc/nginx/app-secrets.env
Línea base de endurecimiento SSH
Además de las claves, el demonio acepta directivas que limitan el alcance de un ataque. PermitRootLogin no obliga a autenticarse como usuario normal antes de usar sudo; AllowGroups grupossistema restringe quién puede abrir sesión; MaxAuthTries 3 corta la conexión tras varios intentos fallidos. Todas viven en /etc/ssh/sshd_config —el archivo del servidor— y no confundas sus opciones con las de ~/.ssh/config, que configura al cliente.
El orden dentro del archivo importa: sshd lee la primera aparición de cada directiva y ignora las posteriores. sshd -T imprime la configuración efectiva sin reiniciar nada, lo que permite verificar que una directiva no quedó anulada más abajo. Después de editar, sshd -t valida la sintaxis, systemctl reload ssh (o sshd, según la distribución) aplica los cambios y la sesión actual se mantiene abierta como vía de reversión.
sudo sshd -t
sudo sshd -T | grep -i permitroot
sudo systemctl reload ssh
Superficie mínima
Cada pieza instalada añade código que parchear y, si arranca o escucha, una puerta que defender. Antes de conservar un paquete por si acaso, pregúntalo en el inventario: sin uso documentado no tiene justificación, y apt remove o dnf remove retiran del sistema lo que nadie necesita. El criterio también aplica a cuentas y módulos: getent passwd enumera cuentas con shell activa que quizá nadie use, y lsmod muestra módulos de kernel cargados que pueden no corresponder al hardware presente.
Reducir la superficie tiene un efecto directo en la ventana de mantenimiento: menos piezas que revisar significa menos tiempo con servicios detenidos y menos dependencias que reprobar cuando cambia una librería compartida. Documenta cada retirada en el inventario para que la próxima revisión no lo confunda con una instalación pendiente.
Actualizaciones y configuración base
Actualizar no es ejecutar un comando y olvidar. Define un ciclo: revisar avisos, probar en un entorno representativo, programar la ventana, aplicar, reiniciar si corresponde y verificar. apt update refresca los índices, apt list --upgradable muestra pendientes y apt upgrade aplica paquetes; en dnf, usa check-update y upgrade. No mezcles repositorios no previstos ni instales paquetes sin firma.
Las actualizaciones automáticas reducen la exposición, pero pueden introducir cambios sin supervisión. En Ubuntu, unattended-upgrades aplica actualizaciones de seguridad según /etc/apt/apt.conf.d/50unattended-upgrades. Habilítalo tras decidir qué repositorios cubre, si reiniciará servicios y cómo se notifican los fallos. Comprueba systemctl status unattended-upgrades y revisa los registros; una política que falla en silencio es peor que una manual conocida.
Una línea base documenta los valores esperados: contraseñas, servicios habilitados, puertos, montajes, zona horaria y agentes. Exprésala como lista de comprobación o como código versionado que compare estado real y deseado. ss -tulpn muestra puertos y procesos; systemctl list-unit-files --state=enabled revela servicios que arrancan solos. Toda desviación se justifica o corrige.
Documentación y gestión de cambios
Un cambio sin registro es una incógnita para quien diagnostica de madrugada. Debe indicar qué se modifica, por qué, quién lo autoriza, cómo se prueba, cómo se revierte y cuándo se cierra. Los cambios pequeños también cuentan: una regla de firewall, una entrada de cron o un paquete alteran un servicio. El registro puede ser un ticket, un commit o un runbook buscable y fechado.
La documentación útil es breve y verificable. Un runbook incluye propósito, dependencias, puertos, configuración y registros, arranque y parada, contactos y recuperación. No dupliques la configuración: enlaza al repositorio y explica las decisiones. Los diagramas de red y dependencias se actualizan cuando cambia la topología, no al final del proyecto.
sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
sudo nginx -t
sudo systemctl reload nginx
Antes de editar, copia el archivo o usa control de versiones; después valida con nginx -t, sshd -t o visudo -c y recarga en lugar de reiniciar cuando el servicio lo permita. Si falla, restaura la copia y vuelve a validar. Prueba la reversión en un entorno controlado: una copia que nunca se restauró no es un plan.
Clasificación de los cambios
No todos los cambios requieren el mismo proceso. Un cambio estándar sigue un procedimiento ya probado —actualizar un paquete de seguridad con la reversión descrita— y puede ejecutarse con la aprobación previa del responsable del servicio. Un cambio normal introduce una novedad, como una regla de firewall o un servicio nuevo, y exige prueba en un entorno no productivo antes de programar la ventana. La urgencia solo salta esa cola cuando el incidente lo justifica, y el registro se completa después, no se omite.
El formato del registro es secundario; lo esencial es que quien llegue de madrugada encuentre qué cambió, cómo se probó y cómo se vuelve atrás. Si el cambio queda aplicado a mitad, el registro debe decir en qué paso se detuvo, para no repetir la parte ya hecha ni dejar el sistema a medias sin aviso.
Registro, auditoría y verificación
Los registros convierten una sospecha en evidencia. journalctl -u nginx --since today filtra por unidad y fecha, y journalctl -p err -b muestra errores del arranque. Para conservarlos entre reinicios, configura Storage=persistent en /etc/systemd/journald.conf y vigila el espacio. /var/log sigue siendo relevante para servicios que escriben fuera del journal, y logrotate evita que crezcan sin control.
La auditoría también confirma accesos y cambios. last muestra inicios de sesión, lastb intentos fallidos y journalctl _COMM=sudo registra ejecuciones de sudo. Compara la lista de administradores con las altas y bajas de personal, y revisa las claves SSH autorizadas: una clave olvidada es una vía de acceso permanente.
journalctl -p err -b --no-pager
journalctl _COMM=sudo --since "1 week ago" --no-pager
last -n 10
ss -tulpn
Define la frecuencia de revisión y deja constancia. La verificación debe producir un resultado observable: ticket cerrado, informe o alerta resuelta. Sin evidencia, la práctica existe solo en la intención.
Verificación de integridad
Los gestores de paquetes guardan el checksum de cada archivo instalado: dpkg -V paquete en Debian y Ubuntu, rpm -Va en Fedora y RHEL, comparan el estado actual con el registrado y marcan los archivos cuyo contenido, permisos o propietario difieren. Ejecutarlos sobre el sistema completo es lento; acótalos a los paquetes críticos después de un incidente o al comienzo de la ventana de mantenimiento.
Para el resto del árbol, herramientas como AIDE mantienen una base de referencia generada tras la instalación y la contrastan después. Una diferencia no prueba una intrusión —también la produce una actualización legítima—, pero obliga a revisar cada archivo que cambió fuera de una ventana conocida, que es exactamente la señal que conviene no perder.
Retención de registros con logrotate
/etc/logrotate.d/ recoge rotaciones por servicio. Una entrada típica para un demonio que escribe en /var/log/ejemplo/*.log combina frecuencia, límites y notificación:
/var/log/ejemplo/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 0640 usuario-ejemplo adm
postrotate
systemctl reload ejemplo >/dev/null 2>&1 || true
endscript
}
daily fija la frecuencia y rotate 14 conserva catorce copias; compress comprime las antiguas y delaycompress espera un ciclo para no comprimir el archivo activo. missingok evita el fallo si el archivo no existe y notifempty salta la rotación si está vacío. create restablece permisos al recrear el archivo, y postrotate avisa al servicio para que reabra el descriptor: sin ese paso, el proceso sigue escribiendo en el archivo renombrado y la rotación no libera espacio real.
logrotate -d /etc/logrotate.d/ejemplo simula la ejecución y detalla lo que haría sin modificar nada, mientras que logrotate -f fuerza una rotación. Comprueba el resultado con ls -l /var/log/ejemplo/ y con el journal de la unidad responsable si la rotación aparece en medio del problema.
Frecuencias de revisión
| Cadencia | Comprobación | Comando de partida |
|---|---|---|
| Diaria | unidades fallidas y errores del arranque | systemctl --failed, journalctl -p err -b |
| Semanal | espacio e inodos, actualizaciones pendientes | df -h, df -i, apt list --upgradable |
| Semanal | altas y bajas frente a las cuentas privilegiadas | getent group sudo, last -n 20 |
| Mensual | puertos expuestos y servicios habilitados | ss -tulpn, systemctl list-unit-files --state=enabled |
| Mensual | respaldos: último éxito y restauración probada | registro del trabajo y prueba en un equipo dedicado |
Anota los valores en cada revisión: el crecimiento de disco o el número de cuentas en el grupo de administradores se observa en la serie temporal, no en una lectura aislada. Un mes sin novedades deja la misma huella fechada que un mes con incidencias; la diferencia está en las cifras, no en el silencio.
Indicadores de la práctica
Lo que no se mide termina sustituyéndose por anécdotas. Cuatro cifras bastan para saber si las prácticas funcionan: hosts sin entrada en el inventario, cuentas con privilegios de administrador respecto al personal vigente, días desde la publicación de un parche de severidad alta hasta su aplicación, y proporción de respaldos con restauración probada en los últimos treinta días.
Saca las cifras de las mismas fuentes que la línea base y guárdalas con fecha en el repositorio de operaciones. Al comparar periodos, una tendencia pesa más que un valor aislado: un único host sin inventario es una excepción, tres meses seguidos con los mismos dos es una deuda con responsable identificable.
Incidentes: primeros pasos y cierre
Cuando un servicio cae, la urgencia corre en contra de la evidencia. Antes de reiniciar, captura el estado: systemctl status <unidad> --no-pager, journalctl -u <unidad> -n 100, ss -tulpn y df -h. Un reinicio borra el proceso, los descriptores y a veces la causa; sin capturas, el diagnóstico empieza de cero y la misma falla volverá a parecer nueva.
Comunica el alcance con datos: qué usuarios ven el fallo, desde cuándo y qué cambió en la ventana previa. Después actúa en orden: revertir el último cambio si es evidente, aislar el componente afectado y escalar con las capturas adjuntas. El incidente termina cuando el servicio funciona y cuando la causa quedó confirmada; escribe la línea de tiempo y, si la causa raíz sigue sin establecerse, dilo explícitamente para que la recurrencia se detecte en los primeros minutos.
systemctl status nginx --no-pager
journalctl -u nginx -n 100 --no-pager
ss -tulpn
df -h
Ejemplos prácticos
Un servidor web ejecuta nginx como root y SSH acepta contraseñas. El administrador crea una unidad con User=www-data, NoNewPrivileges=yes y PrivateTmp=yes, valida con systemd-analyze security y comprueba que el sitio responde. Después desactiva PasswordAuthentication, valida con sshd -t, recarga y confirma el acceso con clave antes de cerrar la sesión anterior.
Para una actualización de seguridad, revisa apt list --upgradable, prueba en staging, programa una ventana y documenta la reversión. Tras aplicar, reinicia los servicios afectados, comprueba systemctl --failed y revisa el journal. Cierra con la versión instalada y la hora de verificación, no solo con "actualizado".
Tras una rotación de personal aparece una clave SSH que nadie reconoce y un proceso de terceros escuchando en 0.0.0.0:9000. Con ss -tulpn se identifica el PID, con systemctl status la unidad que lo arranca y con dpkg -S o rpm -qf el paquete que instaló el binario. Se decide documentarlo o retirarlo según el inventario; en el segundo caso, systemctl disable --now detiene el arranque automático y el gestor de paquetes elimina el resto. El ticket guarda quién encontró el hallazgo, qué evidencia se recogió y qué decisión se tomó.
En una ventana de mantenimiento se actualizan doce hosts con el mismo procedimiento. El primero valida la secuencia completa: comprobar pendientes, instalar, reiniciar los servicios afectados y revisar systemctl --failed antes de seguir. Los once restantes repiten esa secuencia y cada cierre anota hora, versión instalada y resultado; si el tercero falla, se detiene el despliegue y la reversión ya está escrita en el ticket, así que el equipo vuelve al estado anterior sin improvisar.
Errores frecuentes
- Compartir root y creer que
sudoatribuye correctamente las acciones. - Actualizar producción sin probar ni prever reversión.
- Documentar copiando el archivo completo y dejarlo desactualizado.
- Activar actualizaciones automáticas sin revisar repositorios ni notificaciones.
- Revisar logs solo en incidentes, sin línea base ni retención.
- Conceder
NOPASSWD: ALLy perder la trazabilidad.
Puntos clave para el examen
- CIS y NIST CSF ayudan a priorizar; no certifican un sistema.
- Mínimo privilegio: cuentas nominativas,
sudoacotado y servicios sin root. - Actualizar implica probar, programar, aplicar, verificar y revertir.
- La documentación debe ser buscable, fechada y ligada al cambio.
- La auditoría usa journal,
last,lastby registros desudo. - Los secretos viven fuera del repositorio y se rotan cuando quedan expuestos.
sshd -tvalida la sintaxis ysshd -Tmuestra la configuración efectiva del demonio.- La rotación de logs necesita reabrir el descriptor desde
postrotatepara liberar espacio. - Las revisiones sin hallazgos también dejan constancia fechada y comparables en el tiempo.
Recursos externos
Autoevaluación
-
¿Por qué una cuenta compartida de root dificulta la auditoría? Respuesta: Las acciones no se atribuyen a una persona.
sudocon cuentas nominativas registra autoría y permite revocar accesos. -
¿Qué debe incluir un cambio antes de aplicarse? Respuesta: Motivo, alcance, autorización, prueba, ventana y reversión verificada.
-
¿Qué diferencia hay entre
systemctl reloadyrestart? Respuesta:reloadrelee la configuración sin detener el proceso cuando el servicio lo soporta;restartdetiene y arranca, con interrupción breve. -
¿Cómo se comprueba qué puede ejecutar un usuario con sudo? Respuesta: Con
sudo -l -U usuario, que lista las reglas aplicables; el grupo no basta. -
¿Qué evidencia demuestra que una revisión de registros se realizó? Respuesta: Un ticket, informe o alerta resuelta con fecha y conclusión. Los logs no prueban su revisión.
-
¿Qué compruebas antes de recargar el SSH tras editar
sshd_config? Respuesta:sshd -tpara la sintaxis y, si cabe duda,sshd -Tpara la configuración efectiva, manteniendo abierta la sesión actual. -
¿Por qué puede no liberarse espacio tras rotar un log? Respuesta: El proceso conserva el descriptor del archivo renombrado; el
postrotatecon recarga le obliga a reabrirlo. -
¿Dónde deben vivir los secretos de una aplicación? Respuesta: Fuera del repositorio, en archivos con permisos restringidos que el servicio carga con
EnvironmentFile=o el mecanismo propio del gestor. -
¿Cómo identificas qué paquete proporcionó un binario desconocido? Respuesta:
dpkg -S /ruta/al/binarioen Debian y Ubuntu, yrpm -qf /ruta/al/binarioen Fedora y RHEL. -
¿Qué haces si un cambio queda aplicado solo a medias? Respuesta: Detén el avance, anota el paso exacto en el ticket y decide entre completar o restaurar la copia previa; el cambio no se cierra hasta que el estado sea uno de los dos.