OTOthoTools

Generatore systemd

Crea unità più sicure
Risultato.service
[Unit]
Description=Otho worker
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=otho
WorkingDirectory=/opt/otho
ExecStart=/opt/otho/bin/worker
Restart=on-failure
RestartSec=5s
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true

[Install]
WantedBy=multi-user.target

Introduzione

Il generatore systemd produce un'unità di servizio (un file .service) con opzioni di hardening facili da dimenticare: un utente non root, NoNewPrivileges, PrivateTmp, ProtectSystem=strict e ProtectHome.

systemd permette di descrivere cosa un servizio può toccare. L'unità generata è un punto di partenza difendibile per un worker in background, un agente o qualsiasi processo long-running.

Obiettivo

  • Generare un'unità .service sintatticamente corretta da nome, comando, utente e directory di lavoro.
  • Applicare hardening di base: utente dedicato, riavvio su errore, nessun privilegio nuovo, /tmp privato e percorsi di sistema in sola lettura.
  • Mantenere l'unità leggibile affinché un amministratore possa modificarla prima della distribuzione.

Input

  • Descrizione (testo libero).
  • ExecStart — il percorso assoluto dell'eseguibile.
  • Utente del servizio — l'account non privilegiato con cui gira il servizio.
  • Directory di lavoro (opzionale).

Come funziona

Lo strumento assembla tre sezioni. [Unit] dichiara la descrizione e ordina il servizio dopo network-online.target. [Service] imposta Type=simple, utente e directory di lavoro, ExecStart e Restart=on-failure con ritardo di 5 secondi.

Seguono le direttive di hardening: NoNewPrivileges=true blocca l'acquisizione di nuovi privilegi tramite binari setuid; PrivateTmp=true dà al servizio una /tmp propria; ProtectSystem=strict rende l'intero filesystem in sola lettura tranne i percorsi esplicitamente consentiti; ProtectHome=true nasconde /home, /root e /run/user.

[Install] dichiara WantedBy=multi-user.target affinché l'unità possa essere attivata con systemctl enable.

Esempio testabile

Prova — l'analisi gira localmente nel tuo browser.

Esempio

Descrizione: Otho worker
ExecStart:  /opt/otho/bin/worker
Utente:     otho
Directory:  /opt/otho

Output atteso

[Unit]
Description=Otho worker
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=otho
WorkingDirectory=/opt/otho
ExecStart=/opt/otho/bin/worker
Restart=on-failure
RestartSec=5s
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true

[Install]
WantedBy=multi-user.target

Leggere l'output

  • Salva l'output come /etc/systemd/system/<nome>.service, poi esegui sudo systemctl daemon-reload e sudo systemctl start <nome>.
  • Se il servizio deve scrivere nei percorsi di sistema, ProtectSystem=strict lo bloccherà — aggiungi ReadWritePaths o sposta i dati scrivibili nella directory di lavoro.
  • L'unità è un modello: adatta TimeoutStartSec, i limiti di risorse (MemoryMax, CPUQuota) e le capability (CapabilityBoundingSet) al carico.

Rischi

  • Eseguire un servizio come root con accesso di rete è il default più rischioso; l'unità generata lo evita, ma verifica che il tuo binario ExecStart sia di proprietà di root.
  • ProtectSystem=strict può rompere servizi che scrivono fuori dalla loro directory di lavoro — testa prima della produzione.
  • Restart=on-failure non protegge dai crash con exit 0; per worker critici valuta Restart=always.

Limiti

  • Lo strumento genera il file; non può testare che il tuo eseguibile parta o che i suoi permessi siano corretti.
  • Non genera socket activation, timer o grafi di dipendenze complessi.
  • L'hardening è di base: una revisione vera dovrebbe considerare capability, seccomp e namespace di rete.

Riferimenti ufficiali

FAQ

Perché un utente dedicato per ogni servizio?

Un utente dedicato non privilegiato limita cosa può fare un servizio compromesso: non può leggere i file degli altri né scrivere fuori dai propri percorsi. Root va riservato ai pochi servizi che lo richiedono davvero.

Cosa fa NoNewPrivileges=true?

Impedisce al servizio e ai suoi figli di acquisire privilegi tramite binari setuid o meccanismi simili, anche se tali binari esistono sul sistema.

Cos'è ProtectSystem=strict?

Rende l'intero filesystem in sola lettura per il servizio, tranne i percorsi esplicitamente consentiti. È il livello ProtectSystem più forte e si sposa con servizi che scrivono solo nella loro directory di lavoro o in /tmp.