Gestión segura de variables de entorno en unidades de servicio de Systemd

Conozca las mejores prácticas de seguridad para configurar variables de entorno dentro de las unidades de servicio de Systemd. Esta guía detalla cómo utilizar de manera efectiva las directivas `Environment` y `EnvironmentFile`. Hacemos hincapié en el manejo seguro de datos sensibles mediante archivos de configuración externos referenciados a través de las unidades Systemd drop-in, e incluye ejemplos de código prácticos para asegurar permisos de archivo estrictos y verificar las variables cargadas.

38 vistas

Gestión Segura de Variables de Entorno en Unidades de Servicio Systemd

Systemd, como el gestor principal de sistemas y servicios para las distribuciones modernas de Linux, se basa en archivos de unidad de servicio (.service) para definir cómo se inician, detienen y mantienen las aplicaciones. Un aspecto crítico de la configuración de cualquier aplicación moderna es la inyección de configuraciones, rutas y, lo más importante, secretos sensibles como claves de API o credenciales de bases de datos.

La gestión inadecuada de estas variables de entorno puede provocar vulnerabilidades de seguridad, dificultades en la depuración y configuraciones no portables. Esta guía detalla las directivas apropiadas de Systemd —Environment y EnvironmentFile— y demuestra el uso seguro de archivos de configuración 'drop-in' para manejar datos sensibles, garantizando la separación de responsabilidades y prácticas de seguridad robustas.


El Rol de las Variables de Entorno en Systemd

Las variables de entorno proporcionan un mecanismo sencillo para configurar un servicio sin modificar su binario o código. Cuando Systemd inicia un servicio, construye un entorno completo (incluyendo el PATH necesario, variables de usuario/grupo, etc.) e inyecta cualquier variable definida en el archivo de unidad antes de ejecutar el comando ExecStart.

Systemd proporciona dos directivas principales dentro de la sección [Service] de un archivo de unidad para gestionar estas variables.

1. Definición Directa: La Directiva Environment

Este método permite definir variables directamente dentro del archivo de unidad de Systemd. Es adecuado para parámetros de configuración no sensibles que cambian raramente.

Uso y Sintaxis

La directiva Environment acepta una lista separada por espacios de asignaciones de variables en el formato "CLAVE=VALOR".

# /etc/systemd/system/my-app.service

[Unit]
Description=Servicio de Mi Aplicación

[Service]
User=miusuario
WorkingDirectory=/opt/my-app

# Define variables directamente en el archivo de unidad
Environment="APP_PORT=8080" "NODE_ENV=production"

ExecStart=/usr/local/bin/my-app --start

[Install]
WantedBy=multi-user.target

Limitaciones y Seguridad

Aunque conveniente, la directiva Environment nunca debe usarse para información sensible (secretos, contraseñas, claves de API). Los archivos de unidad a menudo se almacenan en sistemas de gestión de configuración o se ubican en directorios accesibles para varios usuarios (incluso si son de solo lectura, podrían ser visibles por usuarios no root dependiendo de la configuración). Codificar secretos directamente compromete los principios de seguridad.

2. Configuración Externa: La Directiva EnvironmentFile

Para configuraciones complejas, variables dinámicas o datos sensibles, cargar variables desde un archivo externo es el método preferido. Esto permite gestionar los permisos del archivo de variables de forma independiente del archivo de unidad principal.

Uso y Sintaxis

La directiva EnvironmentFile toma una ruta absoluta a un archivo de configuración. Systemd lee este archivo línea por línea, tratando cada línea como una posible asignación CLAVE=VALOR.

[Service]
# Carga variables desde un archivo externo
EnvironmentFile=/etc/config/my-app-settings.conf

ExecStart=/usr/local/bin/my-app --start

Formato del Archivo de Entorno

El archivo externo debe adherirse a un formato simple similar a un shell:

  • Las líneas que comienzan con # se tratan como comentarios.
  • Las líneas que comienzan con una asignación de variable vacía (VAR=) borrarán la variable si se estableció previamente.
  • Las variables se definen como CLAVE=VALOR.
  • Se admite el uso de comillas para el valor (CLAVE="VALOR CON ESPACIOS").
# /etc/config/my-app-settings.conf

# Variables no sensibles
MAX_WORKERS=4
LOG_LEVEL=INFO

# Variable sensible (requiere permisos estrictos de archivo)
DB_PASSWORD=SecureRandomString12345

Manejo de Archivos Ausentes

Por defecto, si el archivo especificado por EnvironmentFile no existe, Systemd fallará al iniciar el servicio. Si el archivo de entorno es opcional, puedes prefijar la ruta del archivo con un guion (-):

EnvironmentFile=-/etc/config/optional-settings.conf

Si el archivo está prefijado con -, Systemd ignorará los errores causados por la ausencia del archivo.

Mejor Práctica: Uso de Unidades 'Drop-in' para Datos Sensibles

Modificar el archivo de unidad principal (por ejemplo, /usr/lib/systemd/system/my-app.service) generalmente no se recomienda, especialmente si el archivo es gestionado por un administrador de paquetes. En su lugar, utiliza archivos de unidad 'drop-in' para aplicar anulaciones o adiciones de configuración.

Esta práctica es crucial cuando se trabaja con variables de entorno sensibles, ya que permite separar la configuración estándar del servicio de las rutas de los archivos de secretos locales.

Configuración 'Drop-in' Paso a Paso

1. Localizar/Crear el Directorio 'Drop-in'

Para un servicio llamado my-app.service, el directorio 'drop-in' debe llamarse my-app.service.d/ y residir en la jerarquía /etc/systemd/system/.

sudo mkdir -p /etc/systemd/system/my-app.service.d/

2. Crear la Anulación de Configuración

Crea un archivo dentro del directorio 'drop-in' (por ejemplo, secrets.conf). Este archivo solo necesita la sección [Service] y las directivas específicas que deseas anular o añadir.

# /etc/systemd/system/my-app.service.d/secrets.conf

[Service]
# Carga el archivo seguro de credenciales
EnvironmentFile=/etc/secrets/my-app-credentials.env

3. Asegurar el Archivo de Entorno Externo

Este es el paso de seguridad más crítico. Asegúrate de que el archivo externo que contiene los secretos tenga permisos restrictivos. Idealmente, debería ser propiedad de root:root y solo legible por el usuario root o el propio usuario del servicio.

# Crea el archivo de secretos
sudo touch /etc/secrets/my-app-credentials.env

# Popula el archivo con secretos
sudo sh -c 'echo "DB_PASS=S3cr3tP@ssw0rd" >> /etc/secrets/my-app-credentials.env'

# Establece permisos restrictivos (solo lectura para root)
sudo chmod 600 /etc/secrets/my-app-credentials.env

⚠️ Advertencia de Seguridad: Permisos de Archivo

Si el archivo referenciado por EnvironmentFile contiene credenciales, los permisos deben establecerse en 0600 o más estrictos. Si el archivo es legible por otros usuarios, los secretos se expondrán durante el inicio del servicio o la inspección manual.

Solución de Problemas y Verificación

Después de realizar cualquier cambio en los archivos de unidad o 'drop-ins', debes recargar la configuración del gestor de Systemd.

sudo systemctl daemon-reload
sudo systemctl restart my-app.service

Para verificar qué variables de entorno han sido cargadas exitosamente por Systemd para un servicio en ejecución, usa el comando systemctl show y consulta específicamente la propiedad Environment:

systemctl show my-app.service --property=Environment

Ejemplo de Salida (mostrando variables cargadas):

Environment=APP_PORT=8080 NODE_ENV=production DB_PASS=S3cr3tP@ssw0rd

Si el servicio no se inicia, revisa los registros del servicio usando journalctl -xeu my-app.service. Las razones comunes de fallo relacionadas con las variables de entorno incluyen:

  1. Ruta de archivo incorrecta en EnvironmentFile.
  2. Archivo faltante (y la ruta no estaba prefijada con -).
  3. Sintaxis incorrecta de variable en el archivo de entorno externo (por ejemplo, espacios alrededor del signo =).

Resumen de Mejores Prácticas

Escenario Directiva a Usar Mejor Práctica de Ubicación Consideraciones de Seguridad
Configuración Estática y No Sensible Environment Archivo de unidad directo o 'drop-in' Bajo riesgo de seguridad.
Credenciales Sensibles (Secretos) EnvironmentFile Archivo externo, referenciado a través de un 'drop-in' (*.service.d/) CRÍTICO: El archivo de entorno debe tener permisos 0600.
Modularidad y Anulaciones EnvironmentFile Archivo de unidad 'drop-in' Separa la configuración de los valores predeterminados del proveedor.

Al aprovechar la directiva EnvironmentFile dentro de una unidad 'drop-in' dedicada y asegurando permisos de archivo estrictos, los administradores pueden gestionar las configuraciones de servicio de forma segura y flexible, adhiriéndose a los principios de mínimo privilegio y separación de responsabilidades.