SSD Nodes Learn
Guías Matt ConnorPor Matt Connor · Actualizado 2026-07-24

Cómo ejecutar servicios sin privilegios

Evite el acceso total al servidor limitando el radio de explosión. Use cuentas de sistema dedicadas o la opción DynamicUser de systemd para mayor seguridad.

Por qué no ejecutar todo como root

Root puede hacer cualquier cosa en la máquina: leer cada archivo, cambiar cualquier configuración o borrar todo el sistema. Al ejecutar un servicio como root, se entrega todo ese poder a dicho servicio. Si el servicio tiene un bug que un atacante puede explotar, no solo obtiene el servicio, obtiene root, y root es todo el servidor. Ejecutar como un usuario sin privilegios contiene el daño. Un bug en un servicio que se ejecuta con una cuenta limitada le da al atacante solo lo que esa cuenta puede tocar, lo cual debería ser casi nada.

Este es el principio de menor privilegio: dar a cada parte del sistema exactamente el acceso que necesita para realizar su función, y nada más. Es el hábito más efectivo para limitar el radio de explosión de un compromiso, y en un servidor moderno no cuesta casi nada aplicarlo.

Una cuenta dedicada por servicio

El enfoque clásico es crear un usuario de sistema separado para cada servicio, uno que solo sea dueño de los archivos de ese servicio y no pueda iniciar sesión. Una cuenta de sistema para una web app podría verse así:

sudo useradd --system --no-create-home --shell /usr/sbin/nologin appsvc

Cada flag es importante. --system lo convierte en una cuenta de servicio, no en un login humano. --no-create-home omite un directorio home que no necesita. --shell /usr/sbin/nologin significa que incluso si un atacante logra obtener la cuenta, no puede abrir una shell con ella. La cuenta existe solo para ser dueña de un proceso y sus archivos.

Luego, dé al usuario solo los archivos que necesita, y nada más:

sudo chown -R appsvc:appsvc /opt/myapp

Ahora el servicio lee y escribe en su propio directorio y no tiene razón de estar en ningún otro lugar del disco. Si alguna vez es explotado, los archivos que el atacante puede cambiar se limitan a /opt/myapp; la cuenta aún puede leer cualquier cosa que sea legible por el mundo, pero no puede modificar el resto del sistema.

Deje que systemd lo ejecute como ese usuario

Una vez que la cuenta existe, indique a systemd que ejecute el servicio con ella. En el unit file, una línea lo hace:

[Service]
ExecStart=/opt/myapp/bin/server
User=appsvc
Group=appsvc

User=appsvc significa que el proceso comienza con los privilegios limitados de esa cuenta en lugar de los de root. Esta es la forma normal y estándar de ejecutar una aplicación bajo systemd, y vale la pena hacerlo para cada servicio para el cual escriba un unit.

O salte la cuenta por completo con DynamicUser

systemd puede ir un paso más allá y crear un usuario temporal para usted, uno que solo existe mientras el servicio se ejecuta. Configure DynamicUser=yes y no tendrá que gestionar ninguna cuenta:

[Service]
ExecStart=/opt/myapp/bin/server
DynamicUser=yes
StateDirectory=myapp

Al iniciar, systemd asigna un user ID no utilizado; al detener, lo libera. El servicio también obtiene un /tmp privado, una vista de solo lectura de la mayor parte del filesystem, y un directorio de estado escribible bajo /var/lib/myapp que StateDirectory= configura y le entrega. Para un servicio autónomo que solo necesita su propio directorio de estado, DynamicUser=yes es la forma que requiere menos esfuerzo para obtener un aislamiento fuerte, porque no hay ninguna cuenta de larga duración que un atacante pueda atacar.

Escribir units a mano es laborioso, y configurar correctamente las directivas de hardening es donde reside la mayor parte del valor. El generador en la guía de servicios y timers de systemd puede completar estas opciones por usted para que el unit sea correcto desde la primera vez.

Cómo encaja esto con el resto

El menor privilegio es una capa, y funciona con las demás en lugar de reemplazarlas. Un firewall de denegación por defecto controla qué puede alcanzar al servicio; ejecutarlo como un usuario sin privilegios controla qué puede hacer el servicio si es vulnerado; y SSH endurecido mantiene a los atacantes fuera de la máquina en primer lugar. Ninguna de estas por sí sola es suficiente, y juntas significan que un bug en un servicio no se convierte en un compromiso de todo el servidor.

Antes de continuar, revise una lista de verificación de hardening para toda la máquina y genere una copia personalizada para trabajar:

ToolVPS hardening checklist

FAQ

¿Por qué no debería ejecutar un servicio como root?

Porque root puede hacer cualquier cosa en la máquina; un servicio ejecutado como root que sea explotado entrega al atacante el servidor completo, no solo el servicio. Ejecutar el servicio como una cuenta limitada y sin privilegios contiene el daño a lo que sea que esa cuenta pueda acceder. Reserve root para administración y ejecute cada servicio de larga duración como un usuario restringido.

¿Cómo creo un usuario que no pueda iniciar sesión?

Ejecute sudo useradd --system --no-create-home --shell /usr/sbin/nologin NAME. El shell nologin significa que la cuenta no puede abrir una sesión interactiva incluso si sus credenciales son robadas, --system la marca como cuenta de servicio, y --no-create-home omite un directorio home que no necesita. Dele la propiedad de solo sus propios archivos con chown.

¿Qué es systemd DynamicUser?

DynamicUser=yes le dice a systemd que cree un usuario temporal para el servicio que solo existe mientras este se ejecuta, de modo que nunca gestione una cuenta de larga duración. También le da al servicio un /tmp privado, una vista del filesystem mayormente de solo lectura, y un directorio de estado gestionado. Es la forma que requiere menos esfuerzo para ejecutar un servicio autónomo bajo una identidad temporal de bajos privilegios.

¿Ejecutar como un usuario no-root reemplaza un firewall?

No. Protegen cosas diferentes. Ejecutar como un usuario sin privilegios limita lo que un servicio puede hacer si es vulnerado, mientras que un firewall limita qué puede alcanzar al servicio en absoluto. Use ambos, junto con SSH endurecido, para que cada capa cubra lo que las otras no pueden.

¿Qué archivos debe poseer el usuario del servicio?

Solo los archivos que el servicio realmente necesita, y nada más. Dele a la cuenta la propiedad de su propio directorio de trabajo y sus datos, y deje todo lo demás propiedad de root. Un buen patrón es sudo chown -R svc-app:svc-app /opt/svc-app para el directorio de la aplicación, mientras que la configuración bajo /etc permanece propiedad de root y solo es legible por el servicio. El objetivo es que si el proceso es comprometido, los archivos que puede cambiar se limiten a sus propios datos, no al resto del sistema.

#security#least-privilege#systemd#users#hardening#linux