/etc/sudoers es el archivo que controla exactamente quién puede ejecutar qué comandos como otro usuario (habitualmente root) a través de sudo. No es una lista de contraseñas ni un control de acceso al sistema: es una política de delegación de privilegios. La distinción importa porque te permite dar a un operador acceso a systemctl restart nginx sin darle acceso a passwd o a rm -rf /.
El motivo por el que nunca debes editar /etc/sudoers directamente con vim o nano es simple: si introduces un error de sintaxis, sudo dejará de funcionar completamente. Si en ese momento no tienes acceso físico a la máquina ni una sesión root activa, estás bloqueado. visudo resuelve exactamente ese problema: abre el archivo en tu editor habitual, pero antes de guardarlo valida la sintaxis y te avisa si hay errores. En Debian, visudo usa nano por defecto a menos que hayas configurado EDITOR o VISUAL.
¿Cuándo tocas este archivo? Cuando incorporas un usuario nuevo que necesita privilegios elevados, cuando configuras un usuario de despliegue para pipelines de CI/CD, o cuando necesitas auditar qué tiene acceso a qué en un sistema de producción. Lo que rompe si lo haces mal es variado: desde bloquear completamente sudo (error de sintaxis), hasta abrir una escalación de privilegios no intencionada si escribes una regla demasiado permisiva.
La sintaxis de una regla sigue este esquema:
usuario HOST=(RUNAS) COMANDOS
HOST casi siempre es ALL salvo en entornos con sudoers centralizado. RUNAS indica el usuario y grupo con que se ejecuta el comando. COMANDOS es una lista de rutas absolutas. El directorio /etc/sudoers.d/ permite fragmentar la configuración en archivos separados, lo que es preferible a tocar el archivo principal: cada servicio o rol tiene su propio archivo, y puedes eliminar o auditar permisos sin riesgo de dañar las reglas del resto.
# Ver quién tiene acceso sudo actualmente (requiere ser root o tener sudo) sudo cat /etc/sudoers # Editar /etc/sudoers de forma segura sudo visudo # Dentro de visudo, la línea que da acceso completo al grupo sudo: # %sudo ALL=(ALL:ALL) ALL # El % indica grupo. ALL:ALL significa (usuario:grupo) con que se ejecuta. # Mejor práctica: crear un archivo separado en sudoers.d sudo visudo -f /etc/sudoers.d/deploy # Contenido del archivo /etc/sudoers.d/deploy: # Usuario de CI/CD que puede reiniciar nginx sin contraseña deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx # Verificar que el archivo tiene los permisos correctos (visudo lo hace solo, # pero si lo copias de otro lado, sudoers lo rechazará si no es 0440) sudo chmod 0440 /etc/sudoers.d/deploy # Comprobar que la configuración cargada es válida sin abrir editor sudo visudo -c # Ver los privilegios efectivos del usuario actual sudo -l # Ver los privilegios de otro usuario (requiere ser root) sudo -l -U deploy # Diferencia entre las tres formas de usar sudo: # 1. Ejecutar un solo comando con privilegios de root sudo systemctl status nginx # 2. Abrir un shell como root conservando el entorno del usuario actual # (HOME, PATH y variables del usuario que invoca sudo siguen activas) sudo -s # 3. Abrir un login shell completo como root # (carga /root/.bashrc, /root/.profile; el entorno es el de root) sudo -i # Volver a la sesión normal desde cualquier shell elevado exit
La regla %sudo ALL=(ALL:ALL) ALL del archivo principal merece un momento de atención. El prefijo % indica que sudo es un grupo, no un usuario. ALL=(ALL:ALL) ALL se desglosa así: el primer ALL es el host (cualquiera), (ALL:ALL) es el par usuario:grupo con que puede ejecutarse el comando (cualquier usuario, cualquier grupo), y el último ALL son los comandos permitidos (todos). Esta es la línea que Debian añade automáticamente cuando instalas el paquete sudo y añades tu usuario al grupo sudo.
El archivo que creaste en /etc/sudoers.d/deploy hace algo mucho más quirúrgico. NOPASSWD: es un tag que modifica el comportamiento de la regla a su derecha: desactiva la solicitud de contraseña para ese comando concreto. La ruta /usr/bin/systemctl es absoluta deliberadamente; si escribieras solo systemctl, sudoers lo rechazaría o lo buscaría por PATH, lo que introduce ambigüedad. Fíjate también en que la regla no incluye argumentos: NOPASSWD: /usr/bin/systemctl restart nginx permite exactamente ese subcomando con ese argumento, no systemctl stop nginx ni systemctl daemon-reload. Si quisieras permitir cualquier operación de systemctl, pondrías solo /usr/bin/systemctl sin argumentos, pero eso sería excesivamente permisivo para un usuario de despliegue.
El comportamiento de sudo visudo -c es especialmente útil en Ansible o en scripts de configuración: te devuelve un código de salida 0 si todo está correcto, y puedes integrarlo en un paso de validación antes de distribuir cambios. Si algún archivo en /etc/sudoers.d/ tiene un error, lo identifica por nombre.
La distinción entre sudo -s y sudo -i aparece constantemente en debugging: con sudo -s tu PATH puede no incluir /sbin o /usr/sbin, lo que hace que comandos como ip o fdisk den “command not found” aunque estén instalados. Con sudo -i arrancas con el entorno limpio de root y esas rutas están presentes. Para tareas de administración del sistema, sudo -i es casi siempre la opción correcta; sudo -s tiene su lugar cuando necesitas que ciertos scripts o variables de entorno del usuario actual sigan disponibles.
N° 38