← retour aux snippets

systemctl edit: override propre d'un service

Créer un override drop-in pour ajuster ExecStart, env, Restart et sandbox sans éditer l'unité d'origine.

objectif

Modifier un service systemd proprement via un drop-in (systemctl edit) plutôt qu’en altérant le fichier unité d’origine. Permet de changer ExecStart, variables d’environnement, stratégies de restart et options de sandbox.

code minimal

# créer un override interactif pour data-pm-api.service
sudo systemctl edit data-pm-api.service
# dans l'éditeur, collez:
# [Service]
# Environment="APP_ENV=production" "API_URL=https://api.data.pm"
# Restart=on-failure
# RestartSec=5s
# # remplacer intégralement ExecStart:
# ExecStart=
# ExecStart=/usr/bin/env bash -lc '/usr/bin/node /srv/api.data.pm/server.js'

# appliquer
sudo systemctl daemon-reload
sudo systemctl restart data-pm-api.service
sudo systemctl status data-pm-api.service

utilisation

# 1) override non interactif (drop-in .d/override.conf)
sudo install -d -m 0755 /etc/systemd/system/data-pm-web.service.d
sudo tee /etc/systemd/system/data-pm-web.service.d/override.conf >/dev/null <<'INI'
[Service]
Environment="NODE_ENV=production" "PUBLIC_BASE_URL=https://data.pm"
Restart=on-failure
RestartSec=3s
ExecStart=
ExecStart=/usr/bin/env bash -lc 'cd /srv/data.pm/current && /usr/bin/npm run start'
# sandbox minimale
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=read-only
PrivateTmp=yes
INI
sudo systemctl daemon-reload
sudo systemctl restart data-pm-web.service

# 2) vérifier la configuration effective (unité + drop-ins fusionnés)
systemctl cat data-pm-web.service

# 3) rollback rapide: désactiver temporairement un override
sudo mv /etc/systemd/system/data-pm-web.service.d/override.conf{,.disabled}
sudo systemctl daemon-reload
sudo systemctl restart data-pm-web.service

# 4) injecter un fichier d'environnement dédié plutôt que des Environment= longs
sudo tee /etc/default/data-pm-api >/dev/null <<'ENV'
APP_ENV=production
API_URL=https://api.data.pm
PORT=8080
ENV
sudo tee /etc/systemd/system/data-pm-api.service.d/10-env.conf >/dev/null <<'INI'
[Service]
EnvironmentFile=-/etc/default/data-pm-api
INI
sudo systemctl daemon-reload
sudo systemctl restart data-pm-api.service

variante(s) utile(s)

# A) durcir davantage (capabilities, fs, réseau)
sudo tee /etc/systemd/system/data-pm-api.service.d/20-sandbox.conf >/dev/null <<'INI'
[Service]
CapabilityBoundingSet=
LockPersonality=yes
PrivateDevices=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectControlGroups=yes
IPAddressDeny=any
# autoriser une IP interne si nécessaire:
# IPAddressAllow=10.0.0.5
ReadOnlyPaths=/srv/data.pm
TemporaryFileSystem=/tmp:rw
INI
sudo systemctl daemon-reload
sudo systemctl restart data-pm-api.service

# B) séparer ExecStart dans un drop-in dédié (claireté)
sudo tee /etc/systemd/system/data-pm-api.service.d/00-exec.conf >/dev/null <<'INI'
[Service]
ExecStart=
ExecStart=/usr/bin/node /srv/api.data.pm/server.js
INI
sudo systemctl daemon-reload
sudo systemctl restart data-pm-api.service

# C) timers: override d'un .timer (ex: job d'indexation)
sudo systemctl edit data-pm-index.timer
# [Timer]
# OnCalendar=*:0/10      # toutes les 10 minutes
# RandomizedDelaySec=60  # jitter
sudo systemctl daemon-reload
sudo systemctl restart data-pm-index.timer

# D) appliquer et contrôler sans interrompre (si propriété reloadable)
sudo systemctl reload-or-restart data-pm-api.service

# E) auditer les overrides actifs
systemctl list-unit-files | awk '$1 ~ /^data-pm-.*\.service$/{print $1}' \
 | xargs -r -n1 -I{} bash -lc 'echo "--- {} ---"; systemctl cat {} | sed -n "/\.d\//,/^$/p"'

notes

  • Les overrides se trouvent sous /etc/systemd/system/<unit>.d/*.conf. Ne modifiez pas les unités sous /lib/systemd/system/.
  • Pour remplacer complètement ExecStart, ajoutez d’abord une ligne ExecStart= vide, puis la nouvelle ligne ExecStart=....
  • Après création/modification d’un drop-in, exécutez systemctl daemon-reload, puis restart (ou reload-or-restart).
  • Préférez EnvironmentFile= pour des variables nombreuses; gardez-le en 0640 si sensible et évitez d’y stocker des secrets en clair si possible.
  • Combinez avec des protections (NoNewPrivileges, ProtectSystem, PrivateTmp, CapabilityBoundingSet) pour réduire la surface d’attaque des services.