0Pricing
Linux Command Line & Bash Scripting Mastery · Lektion

Sichere Geheimnisverwaltung und saubere Umgebungen

Halten Sie Zugangsdaten mithilfe von stdin, Dateien und bereinigten Umgebungen aus Prozesslisten und Protokollen heraus.

Sichere Geheimnisverwaltung und saubere Umgebungen ist eine kostenlose Linux Command Line & Bash Scripting Mastery-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Linux Command Line & Bash Scripting Mastery-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Linux Command Line & Bash Scripting Mastery-Kurs umfasst insgesamt 4 Lektionen.

Warum der sichere Umgang mit Geheimnissen wichtig ist

Geheimnisse — API-Schlüssel, Passwörter und Tokens — sind die sensibelsten Daten in jedem System. Der falsche Umgang mit ihnen in Bash-Skripten gehört zu den häufigsten und folgenreichsten Sicherheitsfehlern.

  • Prozesslisten: An Befehle übergebene Argumente erscheinen in ps aux, /proc/<pid>/cmdline und System-Audit-Logs — und sind für alle Benutzer auf dem Host sichtbar.
  • Shell-Verlauf: Interaktiv eingegebene Befehle (und manchmal auch Skripte) werden in ~/.bash_history aufgezeichnet.
  • Logdateien: Traces von set -x, Anwendungslogs und CI/CD-Ausgaben können Variablenwerte erfassen.
  • Weitergabe über die Umgebung: Kindprozesse erben die vollständige Umgebung ihres Elternprozesses, einschließlich aller exportierten Geheimnisse.

Ein gehärtetes Skript behandelt Geheimnisse wie radioaktives Material — minimieren Sie die Zeit der Offenlegung, begrenzen Sie die Angriffsfläche und bereinigen Sie alles auf dem Weg nach außen.

Die Angriffsfläche durch Prozesslisten

Wenn Sie ein Geheimnis als Kommandozeilenargument übergeben, kann es jeder Benutzer des Systems sofort über ps lesen. Das ist keine theoretische Gefahr — sie wird in Shared-Hosting- und Containerumgebungen regelmäßig ausgenutzt.

Das folgende Snippet zeigt das Problem und die Lösung direkt nebeneinander.

#!/usr/bin/env bash
# DANGEROUS: password visible in 'ps aux' output
# curl -u "admin:SuperSecret123" https://api.example.com/data

# SAFE: pass credentials via stdin or a flag that reads from a file
# Many tools support reading secrets from stdin with '-' or dedicated flags:

# Option 1 — pipe the secret so it never appears in argv
echo 'SuperSecret123' | curl -u 'admin' --password-stdin \
  https://api.example.com/data 2>/dev/null || true

# Option 2 — write a temporary netrc and point curl at it
# (covered in a later scene)
echo 'Secret never touches the command line this way'

Geheimnisse aus stdin lesen

Das sicherste interaktive Muster besteht darin, ein Geheimnis zur Laufzeit mit read -rs einzulesen. Das Flag -s unterdrückt die Ausgabe, sodass die Zeichen niemals angezeigt werden, und -r verhindert die Interpretation von Backslashes.

Wichtige Punkte:

  • Die Variable wird niemals exportiert, sodass Kindprozesse sie nicht über /proc/<pid>/environ sehen können.
  • Heben Sie die Variable nach der Verwendung sofort mit unset auf, um das Zeitfenster der Offenlegung zu verkleinern.
  • Vermeiden Sie echo "$SECRET" — verwenden Sie printf '%s', damit kein abschließender Zeilenumbruch den Wert verfälscht und der Wert auch in Traces unsichtbar bleibt.
#!/usr/bin/env bash
set -euo pipefail

# Prompt on stderr so stdout stays clean for piping
read -rsp 'Enter API token: ' API_TOKEN <&2
printf '\n' >&2

# Use the secret — printf keeps it out of argv
response=$(printf '%s' "$API_TOKEN" | curl -sS -X POST \
  -H 'Content-Type: application/json' \
  --data-binary @- \
  https://httpbin.org/post 2>/dev/null) || true

echo "Request sent."

# Scrub immediately — unset removes it from shell memory
unset API_TOKEN

Geheimnisse in Dateien: Berechtigungen und Eigentümerschaft

Wenn ein Geheimnis dauerhaft auf der Festplatte gespeichert werden muss (z. B. ein Schlüssel für ein Dienstkonto), sind die Dateiberechtigungen Ihre wichtigste Schutzmaßnahme.

  • Modus 0600 — nur der Eigentümer darf die Datei lesen und schreiben. Kein Zugriff für Gruppe oder andere Benutzer.
  • Modus 0400 — der Eigentümer darf die Datei nur lesen. Bevorzugen Sie diesen Modus für Schlüssel, die Sie niemals versehentlich überschreiben sollten.
  • Speichern Sie Geheimnisdateien in einem dafür vorgesehenen Verzeichnis wie ~/.secrets/ oder /run/secrets/ (Letzteres ist auf vielen Linux-Systemen ein RAM-basiertes tmpfs und bleibt nur bis zum Neustart erhalten).
  • Legen Sie Geheimnisdateien niemals ohne eine absolut zuverlässige .gitignore in einem von Git überwachten Verzeichnis ab.
#!/usr/bin/env bash
set -euo pipefail

SECRETS_DIR="${HOME}/.secrets"
mkdir -p "$SECRETS_DIR"
chmod 700 "$SECRETS_DIR"   # directory: only owner can list contents

KEY_FILE="${SECRETS_DIR}/api_token"

# Write secret — atomically restrict permissions before writing content
install -m 0600 /dev/null "$KEY_FILE"
printf '%s' 'my-super-secret-token' > "$KEY_FILE"

echo "Permissions:"
ls -la "$KEY_FILE"

# Read back safely — no subshell, no echo
API_TOKEN=$(< "$KEY_FILE")
echo "Token length: ${#API_TOKEN} chars (value not printed)"
unset API_TOKEN

Eine .netrc-Datei mit curl verwenden

curl unterstützt eine Datei ~/.netrc (oder einen beliebigen Pfad über --netrc-file), die Hostnamen den Zugangsdaten zuordnet. Dadurch bleiben Authentifizierungsdaten vollständig aus der Befehlszeile und dem Skripttext heraus.

Das Dateiformat ist einfach:

machine api.example.com
  login admin
  password s3cr3t

Bewährte Vorgehensweisen:

  • Setzen Sie immer chmod 0600 ~/.netrc — auf manchen Systemen verweigert curl die Datei, wenn sie für alle Benutzer lesbar ist.
  • Verwenden Sie --netrc-file /run/secrets/netrc, um auf ein tmpfs-basiertes oder in den Container eingebundenes Geheimnis zu verweisen.
  • Löschen Sie temporäre netrc-Dateien mit einem trap für EXIT.
#!/usr/bin/env bash
set -euo pipefail

TMP_NETRC=$(mktemp)
chmod 0600 "$TMP_NETRC"

# Trap ensures cleanup even on error or signal
trap 'rm -f "$TMP_NETRC"' EXIT

# Write credentials to the temp netrc
cat > "$TMP_NETRC" <<'EOF'
machine httpbin.org
  login myuser
  password mypassword
EOF

curl -fsS --netrc-file "$TMP_NETRC" \
  https://httpbin.org/basic-auth/myuser/mypassword \
  -o /dev/null -w 'HTTP %{http_code}\n' || true

# trap fires here: $TMP_NETRC is deleted
echo 'Temp netrc cleaned up by trap.'

Sicherer Umgang mit Umgebungsvariablen

Umgebungsvariablen sind eine beliebte Möglichkeit, Geheimnisse in Skripte einzuschleusen (12-Factor-Apps, CI/CD-Pipelines). Sie werden jedoch an jeden Kindprozess weitergegeben und sind während der gesamten Lebensdauer des Prozesses unter /proc/<pid>/environ sichtbar.

Schutzmaßnahmen:

  • Übernehmen Sie das Geheimnis sofort in eine lokale Variable und heben Sie die Definition der Umgebungsvariablen auf, damit Kindprozesse sie nicht erben können.
  • Übergeben Sie Geheimnisse mit env -i oder einer Inline-Zuweisung nur an die jeweils benötigten Befehle, statt die vollständige geerbte Umgebung zu verwenden.
  • Verwenden Sie für eine Geheimnisvariable niemals export — verwenden Sie nach Möglichkeit nur eine Zuweisung (ohne export).
#!/usr/bin/env bash
set -euo pipefail

# Simulate a secret arriving via environment (e.g., from CI system)
export DB_PASSWORD='hunter2'   # set by CI — we did not choose this

# Capture locally, then strip from environment immediately
db_password="$DB_PASSWORD"
unset DB_PASSWORD

# Verify the env var is gone before spawning any child process
if printenv DB_PASSWORD 2>/dev/null; then
  echo 'ERROR: DB_PASSWORD still in environment!' >&2
  exit 1
fi

echo 'Secret captured and env var scrubbed.'
echo "Password length: ${#db_password}"
unset db_password

Verhindern, dass Geheimnisse in set -x-Ablaufverfolgungen erscheinen

set -x (xtrace) ist für die Fehlersuche äußerst nützlich, gibt aber den Wert jeder expandierten Variablen auf stderr aus — auch Geheimnisse. Diese Ablaufverfolgungen landen häufig in CI-Protokollen oder im Syslog.

Strategien, um Geheimnisse zu schützen und die Ablaufverfolgung dennoch sinnvoll zu nutzen:

  • Deaktivieren Sie die Ablaufverfolgung während sensibler Vorgänge vorübergehend mit { set +x; } 2>/dev/null.
  • Aktivieren Sie sie anschließend mit set -x wieder.
  • Leiten Sie die xtrace-Ausgabe an einen separaten Dateideskriptor weiter, der in eine geschützte Protokolldatei schreibt, nicht in den öffentlichen Protokollstrom.
#!/usr/bin/env bash
set -euo pipefail
set -x   # tracing ON — safe for non-sensitive sections

echo 'Building application...'
SRC_DIR='/tmp/build'
mkdir -p "$SRC_DIR"

# Disable xtrace around secret handling (suppress the set +x line itself)
{ set +x; } 2>/dev/null

read -rsp 'Token (hidden from trace): ' SECRET_TOKEN <&2
printf '\n' >&2
token_len=${#SECRET_TOKEN}
unset SECRET_TOKEN

set -x  # tracing back ON

echo "Token captured (length=$token_len). Continuing build..."
ls "$SRC_DIR"

Geheimnisse aus Protokolldateien entfernen

Selbst bei sorgfältigem Vorgehen gelangen Geheimnisse manchmal in die Protokollausgabe — insbesondere in ausführlichen oder älteren Skripten. Eine Wrapper-Funktion für die Protokollierung, die bekannte Muster schwärzt, bietet eine zusätzliche Sicherheitsstufe.

Dieses Muster verwendet eine regex-basierte Ersetzung für die gesamte Protokollausgabe. Es ist eine letzte Sicherheitsebene und kein Ersatz für die bereits behandelten Maßnahmen zum sicheren Umgang.

#!/usr/bin/env bash
set -euo pipefail

# A logging function that scrubs common secret patterns before writing
log() {
  local line
  # Replace anything that looks like key=VALUE or password=VALUE
  line=$(printf '%s\n' "$*" \
    | sed -E 's/(password|token|secret|key)=[^[:space:]]*/\1=***REDACTED***/gi')
  printf '[%s] %s\n' "$(date -u '+%T')" "$line"
}

# Usage:
log 'Connecting to database with password=hunter2'
log 'Loaded API token=sk-abc123xyz secret'
log 'Build step completed successfully'   # unchanged

Isolierte Umgebungen mit env -i

env -i startet einen Befehl mit einer vollständig leeren Umgebung und verhindert, dass geerbte Variablen — einschließlich versehentlich übergebener Geheimnisse — den Kindprozess erreichen. Anschließend übergeben Sie ausdrücklich nur die benötigten Variablen.

Das ist besonders nützlich, wenn Sie nicht vertrauenswürdige Skripte, Build-Tools oder Dienstprogramme von Drittanbietern ausführen, die Umgebungsdaten nach außen übertragen könnten.

#!/usr/bin/env bash
set -euo pipefail

# Polluted parent environment (simulating a CI runner)
export AWS_SECRET_ACCESS_KEY='AKIAIOSFODNN7EXAMPLE'
export GITHUB_TOKEN='ghp_faketoken123'
export HOME="$HOME"
export PATH="$PATH"

echo '--- Child sees full environment:'
env | grep -E 'AWS|GITHUB' | head -5

echo '--- Sanitised child (env -i) sees nothing secret:'
env -i HOME="$HOME" PATH="$PATH" TERM="${TERM:-dumb}" \
  bash -c 'env | grep -E "AWS|GITHUB" || echo "No secrets visible"'

unset AWS_SECRET_ACCESS_KEY GITHUB_TOKEN

Temporäre Geheimnisdateien auf tmpfs

tmpfs ist ein RAM-basiertes Dateisystem. Dort geschriebene Dateien werden niemals auf die Festplatte ausgelagert, wodurch das Risiko entfällt, dass Geheimnisse in Swap, im Festplattencache oder in Snapshots erhalten bleiben.

  • Unter Linux sind /dev/shm und /run/user/<uid> normalerweise tmpfs-Einhängungen.
  • Verwenden Sie tmpfs immer zusammen mit einem trap EXIT, um Dateien beim Beenden des Skripts zu löschen.
  • In Containern (Docker, Kubernetes) können Geheimnisse direkt als tmpfs-Volumes in /run/secrets eingebunden werden.
#!/usr/bin/env bash
set -euo pipefail

# Prefer /run/user/$UID (user-owned tmpfs) or /dev/shm (world-readable dir!)
if [[ -d "/run/user/$UID" ]]; then
  TMPFS_DIR="/run/user/$UID"
elif [[ -d '/dev/shm' ]]; then
  TMPFS_DIR='/dev/shm'
else
  # Fallback: warn that disk will be used
  echo 'WARNING: No tmpfs available; using /tmp (disk-backed)' >&2
  TMPFS_DIR='/tmp'
fi

SECRET_FILE=$(mktemp "${TMPFS_DIR}/secret.XXXXXX")
chmod 0600 "$SECRET_FILE"
trap 'shred -u "$SECRET_FILE" 2>/dev/null || rm -f "$SECRET_FILE"' EXIT

printf '%s' 'my-runtime-token' > "$SECRET_FILE"
echo "Secret stored in: $SECRET_FILE"
df -T "$SECRET_FILE" | awk 'NR==2 {print "Filesystem type:", $2}'

# Use the secret...
token=$(< "$SECRET_FILE")
echo "Token length: ${#token}"
unset token
# trap fires on exit: file shredded

Alles zusammenführen: Ein gehärtetes Deployment-Skript

Das folgende Skript kombiniert alle Techniken dieser Lektion zu einem realistischen Deployment-Hilfsskript. Achten Sie darauf, wie jede Schutzschicht die anderen verstärkt:

  • Lesen von stdin mit -s — keine Anzeige im Terminal
  • Geheimnisdatei auf tmpfs mit Bereinigung durch trap
  • Bereinigung der Umgebung — Geheimnis wird vor jedem Unterprozess entfernt
  • xtrace-Schutz — Ablaufverfolgung wird während sensiblen Codes pausiert
  • Schwärzen von Protokollen — Sicherheitsnetz per regex vor dem Schreiben in die Protokolldatei
#!/usr/bin/env bash
set -euo pipefail

### 1. Redacting logger
log() {
  local msg
  msg=$(printf '%s' "$*" \
    | sed -E 's/(password|token|secret|key)=[^[:space:]]*/\1=***/gi')
  printf '[%s] %s\n' "$(date -u +%T)" "$msg"
}

### 2. tmpfs secret store
TMPFS_DIR="${XDG_RUNTIME_DIR:-/tmp}"
SECRET_FILE=$(mktemp "${TMPFS_DIR}/deploy_token.XXXXXX")
chmod 0600 "$SECRET_FILE"
trap 'rm -f "$SECRET_FILE"; log "Secret file cleaned up."' EXIT

### 3. Read secret without trace
{ set +x; } 2>/dev/null
read -rsp 'Deploy token: ' _tok <&2; printf '\n' >&2
printf '%s' "$_tok" > "$SECRET_FILE"
unset _tok
set -x

### 4. Scrub inherited env vars before subprocess
unset DEPLOY_TOKEN 2>/dev/null || true

log 'Starting deployment...'
# Simulate deploy using secret from file (token never in argv)
# curl -H "Authorization: Bearer $(< $SECRET_FILE)" https://api.example.com/deploy
log 'Deployment complete. token=hidden_by_redactor'

echo 'Done.'

Wissenscheck: Offenlegung von Geheimnissen über die Prozessliste

Testen Sie Ihr Verständnis dafür, wie Geheimnisse über Prozesslisten durchsickern und wie Sie dies verhindern.

Lektionsrückblick: Sicherer Umgang mit Geheimnissen

Sie haben Secure Secret Handling and Environment Hygiene abgeschlossen. Hier finden Sie eine kompakte Übersicht über alle behandelten Themen:

  • Prozesslisten: Übergeben Sie Geheimnisse niemals als Befehlszeilenargumente — sie erscheinen in ps aux und /proc/<pid>/cmdline. Verwenden Sie stattdessen eine Weiterleitung über stdin oder --netrc-file.
  • Lesen aus stdin: Verwenden Sie read -rs, um Geheimnisse interaktiv einzulesen, ohne sie im Terminal anzuzeigen oder der Shell-Historie auszusetzen.
  • Dateiberechtigungen: Geheimnisdateien müssen mit chmod 0600 (oder 0400) geschützt werden. Verwenden Sie install -m 0600 für eine atomare Erstellung.
  • netrc-Dateien: Überlassen Sie die Zugangsdaten einer temporären Datei, auf die mit --netrc-file verwiesen wird; löschen Sie sie mit trap EXIT.
  • Sicherer Umgang mit der Umgebung: Entfernen Sie geheime Umgebungsvariablen unmittelbar nach der lokalen Übernahme mit unset; verwenden Sie export niemals unnötig; nutzen Sie env -i zur Isolierung von Kindprozessen.
  • xtrace-Schutz: Schließen Sie sensiblen Code in { set +x; } 2>/dev/null ... set -x ein, damit Debug-Ablaufverfolgungen keine Werte preisgeben.
  • Schwärzen von Protokollen: Verwenden Sie einen auf sed basierenden Logger als Sicherheitsnetz für den Notfall.
  • tmpfs: Speichern Sie Laufzeitgeheimnisse in /run/user/$UID oder /dev/shm, damit sie niemals auf die Festplatte gelangen; löschen Sie sie beim Beenden sicher.

Das entscheidende Prinzip ist der gestaffelte Schutz: Keine einzelne Maßnahme reicht aus, aber durch ihre Kombination wird das Durchsickern von Geheimnissen äußerst schwierig.

Häufig gestellte Fragen

Ist die Lektion „Sichere Geheimnisverwaltung und saubere Umgebungen“ kostenlos?

Ja — der vollständige Text von „Sichere Geheimnisverwaltung und saubere Umgebungen“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Linux Command Line & Bash Scripting Mastery-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Linux Command Line & Bash Scripting Mastery-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Sichere Geheimnisverwaltung und saubere Umgebungen“?

Halten Sie Zugangsdaten mithilfe von stdin, Dateien und bereinigten Umgebungen aus Prozesslisten und Protokollen heraus. Du übst Linux Command Line & Bash Scripting Mastery mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Linux Command Line & Bash Scripting Mastery zu starten?

Keine Vorkenntnisse erforderlich. Linux Command Line & Bash Scripting Mastery auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.

Wie lange dauert die Lektion „Sichere Geheimnisverwaltung und saubere Umgebungen“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Linux Command Line & Bash Scripting Mastery-Lektion Code schreiben und ausführen?

Ja. Jede Linux Command Line & Bash Scripting Mastery-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Command- und Argument-Injection verhindern
  2. Sichere Geheimnisverwaltung und saubere Umgebungen
  3. Ausführung mit geringsten Berechtigungen und sudo-Disziplin
  4. Statische Analyse und Prüfung mit ShellCheck
← Zurück zu Linux Command Line & Bash Scripting Mastery