Files
opencrm/tools/audit-notary/entrypoint.sh
T
duffyduckandClaude Opus 5 601fb03b22 Gegenbuch-Container: Rechte am Bind-Mount selbst geraderuecken
Fehlerbild aus dem echten Betrieb: "mkdir: cannot create directory
'/gegenbuch/schluessel': Permission denied", Container in der
Neustart-Schleife. Ursache: Das Datenverzeichnis kommt als Bind-Mount vom Host;
der Betreiber hatte das Projekt als root geklont, der Container lief aber
direkt als UID 1000 und durfte dort nichts anlegen. Der .gitkeep-Ansatz hatte
stillschweigend angenommen, dass als normaler Benutzer geklont wird - auf einem
Server ist root der Normalfall.

Fix: Der Container startet als root, setzt /gegenbuch per chown auf den
Arbeitsbenutzer (PUID/PGID, Standard 1000) und startet sich per setpriv als
dieser neu. Die eigentliche Arbeit laeuft weiterhin unprivilegiert. Schlaegt
das chown fehl (rootless Docker), gibt es einen Hinweis mit dem passenden
Host-Befehl statt eines stummen Abbruchs.

Verifiziert mit exakt der Ausgangslage: Datenverzeichnis auf root:root gesetzt,
Container gestartet -> laeuft durch, erzeugte Dateien gehoeren 1000:1000, der
private Schluessel liegt mit 0600.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 19:51:10 +02:00

88 lines
3.6 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# Gegenbuch-Schleife: einrichten, dann in festem Takt beglaubigen.
set -uo pipefail
: "${INSTANZ:?INSTANZ fehlt (z. B. prod oder staging)}"
: "${CRM_URL:?CRM_URL fehlt von welcher OpenCRM-Instanz soll geholt werden?}"
: "${CRM_EMAIL:?CRM_EMAIL fehlt Dienstkonto im CRM mit dem Recht audit:read}"
: "${CRM_PASSWORD:?CRM_PASSWORD fehlt Passwort dieses Dienstkontos}"
INTERVALL="${NOTARY_INTERVAL:-3600}"
BUCH=/gegenbuch/buch
SCHLUESSEL=/gegenbuch/schluessel
export NOTARY_STATE_FILE=/gegenbuch/beobachtungen.jsonl
export NOTARY_ALLOW_LOCAL=true # Buch liegt auf dieser Maschine
export NOTARY_PUSH=false # es gibt kein Ziel zum Pushen
# --- Rechte geraderuecken, dann Privilegien abgeben ------------------------
# Laeuft der Container als root, gehoert das Bind-Mount-Verzeichnis vermutlich
# ebenfalls root (typisch, wenn das Projekt als root geklont wurde). Wir setzen
# es auf den Arbeitsbenutzer um und starten uns selbst als dieser neu.
BENUTZER_UID="${PUID:-1000}"
BENUTZER_GID="${PGID:-1000}"
if [ "$(id -u)" = "0" ]; then
if ! chown -R "$BENUTZER_UID:$BENUTZER_GID" /gegenbuch 2>/dev/null; then
echo "[$INSTANZ] HINWEIS: Rechte auf /gegenbuch liessen sich nicht setzen." >&2
echo "[$INSTANZ] Falls es gleich an fehlenden Schreibrechten scheitert, auf dem Host:" >&2
echo "[$INSTANZ] chown -R $BENUTZER_UID:$BENUTZER_GID <datenverzeichnis>" >&2
fi
exec setpriv --reuid="$BENUTZER_UID" --regid="$BENUTZER_GID" --init-groups \
--inh-caps=-all "$0" "$@"
fi
echo "[$INSTANZ] Gegenbuch startet Quelle: $CRM_URL, Takt: ${INTERVALL}s"
# --- Signaturschlüssel: einmalig auf DIESER Maschine erzeugen ---------------
# Er verlässt den Rechner nie. OpenCRM kennt ihn nicht.
mkdir -p "$SCHLUESSEL"
if [ ! -f "$SCHLUESSEL/id_ed25519" ]; then
echo "[$INSTANZ] Erzeuge Signaturschlüssel..."
ssh-keygen -t ed25519 -f "$SCHLUESSEL/id_ed25519" -N "" -C "gegenbuch-$INSTANZ" -q
fi
chmod 600 "$SCHLUESSEL/id_ed25519"
if [ ! -f "$SCHLUESSEL/allowed_signers" ]; then
echo "gegenbuch-$INSTANZ namespaces=\"git\" $(cat "$SCHLUESSEL/id_ed25519.pub")" \
> "$SCHLUESSEL/allowed_signers"
fi
# --- Buch anlegen, falls noch nicht vorhanden ------------------------------
if [ ! -d "$BUCH/.git" ]; then
echo "[$INSTANZ] Lege Gegenbuch an..."
mkdir -p "$BUCH"
git -C "$BUCH" init -q -b main
fi
cd "$BUCH" || exit 1
git config user.email "${NOTAR_EMAIL:-gegenbuch@localhost}"
git config user.name "Gegenbuch $INSTANZ"
git config gpg.format ssh
git config user.signingkey "$SCHLUESSEL/id_ed25519.pub"
git config gpg.ssh.allowedSignersFile "$SCHLUESSEL/allowed_signers"
# Ein erster Commit, damit es eine Historie gibt, an die angehängt werden kann.
if ! git rev-parse HEAD >/dev/null 2>&1; then
git commit -q -S --allow-empty -m "Gegenbuch $INSTANZ angelegt"
fi
# --- Schleife ---------------------------------------------------------------
# Jeder Rückgabecode außer 0 gehört angesehen. Der letzte Stand steht
# zusätzlich in status.txt, damit eine Überwachung ihn abgreifen kann, ohne
# Logs zu durchsuchen.
while true; do
ZEIT=$(date -Iseconds)
node /opt/notary/notary.mjs
CODE=$?
case $CODE in
0) LAGE="in Ordnung" ;;
1) LAGE="Betriebsfehler (Konfiguration, CRM nicht erreichbar, Commit)" ;;
2) LAGE="BEFUND Widerspruch zwischen CRM und Gegenbuch" ;;
3) LAGE="nicht abschliessend feststellbar (u. a. erster Lauf)" ;;
4) LAGE="Gedaechtnis fehlt Bestaetigung noetig, siehe README" ;;
5) LAGE="Anker unvollstaendig" ;;
*) LAGE="unbekannter Code" ;;
esac
echo "[$INSTANZ] $ZEIT exit=$CODE ($LAGE)"
printf '%s exit=%s %s\n' "$ZEIT" "$CODE" "$LAGE" > /gegenbuch/status.txt
sleep "$INTERVALL"
done