gitrust.service 112 lignes · 4421 octets
# =============================================================================
# Gitrust — unité systemd avec hardening
# =============================================================================
# Déploiement :
#   sudo cp template/systemd/gitrust.service /etc/systemd/system/gitrust.service
#   sudo systemctl daemon-reload
#   sudo systemctl enable --now gitrust
#   sudo systemctl status gitrust
#
# Prérequis :
#   - Binaire installé dans /opt/gitrust/gitrust (chmod 755, owned by root)
#   - Utilisateur et groupe système créés :
#       sudo useradd --system --no-create-home --shell /usr/sbin/nologin gitrust
#   - Répertoire de données créé et attribué :
#       sudo mkdir -p /opt/gitrust/data/repos /opt/gitrust/data/ssh_keys
#       sudo chown -R gitrust:gitrust /opt/gitrust/data
#   - Fichier .env placé dans /opt/gitrust/.env (chmod 640, owned by root:gitrust)
# =============================================================================

[Unit]
Description=Gitrust - Self-hosted Git platform
Documentation=https://gitrust.eu/docs
After=network.target postgresql.service
# postgresql.service : décommenter si PostgreSQL tourne sur la même machine.
# Retirer si PostgreSQL est distant (le service ne doit pas bloquer au démarrage).
Wants=network.target

[Service]
Type=simple
User=gitrust
Group=gitrust
WorkingDirectory=/opt/gitrust
EnvironmentFile=/opt/gitrust/.env
ExecStart=/opt/gitrust/gitrust
Restart=on-failure
RestartSec=5

# -------------------------------------------------------------------------
# Hardening systemd
# -------------------------------------------------------------------------

# Interdit d'acquérir de nouveaux privilèges via execve (setuid/setgid binaires)
NoNewPrivileges=true

# Système de fichiers racine en lecture seule (hors ReadWritePaths ci-dessous)
ProtectSystem=strict

# Répertoires home des utilisateurs inaccessibles
ProtectHome=true

# /tmp et /var/tmp privés et isolés du reste du système
PrivateTmp=true

# Périphériques physiques inaccessibles (/dev/sda, /dev/mem, etc.)
PrivateDevices=true

# Espace de noms réseau partagé avec l'hôte (gitrust a besoin du réseau)
# PrivateNetwork=false  # valeur par défaut, laisser commenté

# Protège le kernel et les paramètres systèmes (/proc/sys, /sys, etc.)
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectKernelLogs=true
ProtectControlGroups=true

# Restreint les appels système aux familles nécessaires pour Rust/tokio/git2
SystemCallArchitectures=native

# Limite les familles d'appels système autorisés
# @system-service couvre les appels standards pour un serveur (network, io, process)
SystemCallFilter=@system-service @network-io @file-system @io-event @process

# Interdit d'écrire en mémoire exécutable (exploits JIT/shellcode)
MemoryDenyWriteExecute=true

# Interdit de modifier les capabilities du processus
RestrictRealtime=true
LockPersonality=true

# Limite les namespaces créables (gitrust n'a pas besoin de créer de namespaces)
RestrictNamespaces=true

# -------------------------------------------------------------------------
# Chemins en écriture — tout le reste est en lecture seule (ProtectSystem=strict)
# -------------------------------------------------------------------------
# Repos git bare, clé hôte SSH, workspaces CI temporaires
ReadWritePaths=/opt/gitrust/data
# Workspace CI (si CI_WORKSPACE_PATH pointe ailleurs que /opt/gitrust/data)
# ReadWritePaths=/var/lib/gitrust-ci

# -------------------------------------------------------------------------
# Ports privilégiés (< 1024)
# -------------------------------------------------------------------------
# Décommenter UNIQUEMENT si gitrust doit écouter directement sur :80 ou :22.
# En configuration normale (nginx devant, SSH sur :2222), cette ligne est inutile.
# AmbientCapabilities=CAP_NET_BIND_SERVICE

# -------------------------------------------------------------------------
# Journalisation
# -------------------------------------------------------------------------
StandardOutput=journal
StandardError=journal
SyslogIdentifier=gitrust

# -------------------------------------------------------------------------
# Limites de ressources
# -------------------------------------------------------------------------
# Nombre de fichiers ouverts — gros dépôts git2 + connexions SSH simultanées
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target