0Pricing
Linux Command Line & Bash Scripting Mastery · Lezione

Gestire i segreti in sicurezza e mantenere pulito l'ambiente

Tenga le credenziali fuori dagli elenchi dei processi e dai log usando stdin, file e ambienti ripuliti.

Gestire i segreti in sicurezza e mantenere pulito l'ambiente è una lezione Linux Command Line & Bash Scripting Mastery gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Linux Command Line & Bash Scripting Mastery, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Linux Command Line & Bash Scripting Mastery include 4 lezioni in totale.

Perché è importante gestire correttamente i segreti

I segreti, come chiavi API, password e token, sono i dati più sensibili di qualsiasi sistema. Gestirli in modo errato negli script Bash è uno degli errori di sicurezza più comuni e dannosi.

  • Elenco dei processi: gli argomenti passati ai comandi compaiono in ps aux, /proc/<pid>/cmdline e nei log di audit del sistema, risultando visibili a tutti gli utenti dell'host.
  • Cronologia della shell: i comandi digitati interattivamente (e talvolta gli script) vengono registrati in ~/.bash_history.
  • File di log: le tracce di set -x, i log delle applicazioni e l'output CI/CD possono acquisire i valori delle variabili.
  • Fuga nell'ambiente: i processi figli ereditano l'intero ambiente del processo padre, inclusi gli eventuali segreti esportati.

Uno script adeguatamente protetto tratta i segreti come materiale radioattivo: riduce al minimo il tempo di esposizione, limita la superficie esposta e sanifica ogni elemento prima che esca.

La superficie d'attacco dell'elenco dei processi

Quando passate un segreto come argomento dalla riga di comando, ogni utente del sistema può leggerlo immediatamente tramite ps. Non è un rischio teorico: viene sfruttato regolarmente negli ambienti di hosting condiviso e nei container.

Il frammento qui sotto mostra il problema e la correzione affiancati.

#!/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'

Lettura dei segreti da stdin

Il modello interattivo più sicuro consiste nel leggere un segreto al momento dell'esecuzione usando read -rs. Il flag -s impedisce l'eco, così i caratteri non vengono mai visualizzati, mentre -r impedisce l'interpretazione delle barre rovesciate.

Punti chiave:

  • La variabile non viene mai esportata, quindi i processi figli non possono vederla tramite /proc/<pid>/environ.
  • Dopo l'uso, eliminate immediatamente la variabile con unset per ridurre la finestra di esposizione.
  • Evitate echo "$SECRET": usate printf '%s' per impedire che una nuova riga finale alteri il valore e per mantenerlo invisibile nelle tracce.
#!/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

Segreti nei file: permessi e proprietà

Quando un segreto deve essere conservato su disco (ad esempio, la chiave di un account di servizio), i permessi del file sono la vostra prima linea di difesa.

  • Modalità 0600 — leggibile e modificabile solo dal proprietario. Nessun accesso per il gruppo o per gli altri utenti.
  • Modalità 0400 — di sola lettura per il proprietario. Preferitela per le chiavi che non dovreste mai sovrascrivere accidentalmente.
  • Conservate i file dei segreti in una directory dedicata, ad esempio ~/.secrets/ o /run/secrets/ (quest'ultima è un tmpfs basato sulla RAM in molti sistemi Linux e sopravvive solo fino al riavvio).
  • Non collocate mai i file dei segreti all'interno di una directory monitorata da git senza un file .gitignore assolutamente affidabile.
#!/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

Usare un file .netrc con curl

curl supporta un file ~/.netrc (o un percorso arbitrario tramite --netrc-file) che associa i nomi host alle credenziali. In questo modo i dati di autenticazione restano completamente fuori dalla riga di comando e dal corpo dello script.

Il formato del file è semplice:

machine api.example.com
  login admin
  password s3cr3t

Buone pratiche:

  • Impostate sempre chmod 0600 ~/.netrc: su alcuni sistemi curl rifiuta il file se è leggibile da tutti.
  • Usate --netrc-file /run/secrets/netrc per indicare un segreto basato su tmpfs o iniettato nel container.
  • Eliminate i file netrc temporanei con un trap su 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.'

Gestione sicura delle variabili d'ambiente

Le variabili d'ambiente sono un metodo diffuso per inserire segreti negli script (applicazioni 12-factor, pipeline CI/CD). Tuttavia, vengono esposte a ogni processo figlio e compaiono in /proc/<pid>/environ per tutta la durata del processo.

Strategie difensive:

  • Importate immediatamente il segreto in una variabile locale e annullate la variabile d'ambiente con unset, in modo che i processi figli non possano ereditarla.
  • Passate i segreti ai comandi specifici usando env -i o un'assegnazione inline, invece di usare l'intero ambiente ereditato.
  • Non eseguite mai export su una variabile contenente un segreto: quando possibile, usate soltanto l'assegnazione (senza 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

Impedire la comparsa dei segreti nelle tracce di set -x

set -x (xtrace) è prezioso per il debug, ma stampa il valore di ogni variabile che espande, inclusi i segreti, sullo standard error. Queste tracce finiscono spesso nei log CI o in syslog.

Strategie per proteggere i segreti mantenendo utile il tracing:

  • Disabilitate temporaneamente il tracing intorno alle operazioni sensibili con { set +x; } 2>/dev/null.
  • Riattivatelo in seguito con set -x.
  • Reindirizzate l'output di xtrace a un descrittore di file separato, diretto a un file di log protetto anziché al flusso di log pubblico.
#!/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"

Rimuovere i segreti dai file di log

Anche prestando attenzione, a volte i segreti finiscono nell'output dei log, soprattutto negli script dettagliati o legacy. Una funzione wrapper per il logging che oscura i pattern noti aggiunge una rete di sicurezza.

Questo pattern usa una sostituzione basata su regex su tutto l'output dei log. È un livello di ultima istanza, non un sostituto delle altre pratiche di gestione sicura già illustrate.

#!/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

Ambienti isolati con env -i

env -i avvia un comando con un ambiente completamente vuoto, impedendo a qualsiasi variabile ereditata, inclusi i segreti accidentali, di raggiungere il processo figlio. In seguito si passano esplicitamente solo gli elementi necessari.

È particolarmente utile quando si eseguono script non attendibili, strumenti di build o utilità di terze parti che potrebbero sottrarre dati dall'ambiente.

#!/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

File temporanei dei segreti su tmpfs

tmpfs è un filesystem basato sulla RAM. I file scritti al suo interno non vengono mai salvati su disco, eliminando il rischio che i segreti sopravvivano nella swap, nella cache del disco o negli snapshot.

  • Su Linux, /dev/shm e /run/user/<uid> sono in genere mount tmpfs.
  • Associate sempre l'uso di tmpfs a un trap EXIT per eliminare i file al termine dello script.
  • Nei container (Docker, Kubernetes), i segreti possono essere montati direttamente come volumi tmpfs in /run/secrets.
#!/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

Riunire tutto: uno script di deployment rinforzato

Lo script seguente combina tutte le tecniche di questa lezione in un helper di deployment realistico. Osservate come ogni livello di difesa rafforzi gli altri:

  • lettura da stdin con -s — nessuna visualizzazione nel terminale
  • file dei segreti su tmpfs con pulizia tramite trap
  • pulizia dell'ambiente — il segreto viene annullato prima di qualsiasi processo secondario
  • protezione da xtrace — la traccia viene sospesa intorno al codice sensibile
  • oscuramento dei log — una regex di sicurezza prima della scrittura nel log
#!/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.'

Verifica delle conoscenze: esposizione dei segreti tramite l'elenco dei processi

Verificate la vostra comprensione di come i segreti possano trapelare attraverso gli elenchi dei processi e di come impedirlo.

Riepilogo della lezione: gestione sicura dei segreti

Avete completato Gestione sicura dei segreti e delle variabili d'ambiente. Ecco un riferimento conciso a tutti gli argomenti trattati:

  • Elenchi dei processi: non passate mai i segreti come argomenti della riga di comando: compaiono in ps aux e /proc/<pid>/cmdline. Usate invece il piping tramite stdin o --netrc-file.
  • Lettura da stdin: usate read -rs per acquisire i segreti interattivamente senza visualizzarli nel terminale né esporli nella cronologia della shell.
  • Permessi dei file: i file dei segreti devono avere chmod 0600 (o 0400). Usate install -m 0600 per una creazione atomica.
  • File netrc: delegate le credenziali a un file temporaneo indicato da --netrc-file; eliminate il file con trap EXIT.
  • Gestione dell'ambiente: eseguite immediatamente unset sulle variabili d'ambiente contenenti segreti dopo averle acquisite localmente; non eseguite mai export su di esse senza necessità; usate env -i per isolare i processi figli.
  • Protezione da xtrace: racchiudete il codice sensibile in { set +x; } 2>/dev/null ... set -x per impedire che le tracce di debug rivelino i valori.
  • Oscuramento dei log: usate un logger basato su sed come rete di sicurezza di ultima istanza.
  • tmpfs: conservate i segreti usati a runtime in /run/user/$UID o /dev/shm, in modo che non tocchino mai il disco; distruggeteli all'uscita.

La difesa in profondità è il principio fondamentale: nessuna singola misura è sufficiente, ma combinarle rende estremamente difficile la fuga dei segreti.

Domande Frequenti

La lezione «Gestire i segreti in sicurezza e mantenere pulito l'ambiente» è gratuita?

Sì — il testo completo di «Gestire i segreti in sicurezza e mantenere pulito l'ambiente» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Linux Command Line & Bash Scripting Mastery, passa a CoddyKit PRO. Il corso Linux Command Line & Bash Scripting Mastery include 4 lezioni in totale.

Cosa imparerò in «Gestire i segreti in sicurezza e mantenere pulito l'ambiente»?

Tenga le credenziali fuori dagli elenchi dei processi e dai log usando stdin, file e ambienti ripuliti. Eserciti Linux Command Line & Bash Scripting Mastery con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Linux Command Line & Bash Scripting Mastery?

Non è richiesta alcuna esperienza precedente. Linux Command Line & Bash Scripting Mastery su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.

Quanto tempo richiede la lezione «Gestire i segreti in sicurezza e mantenere pulito l'ambiente»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Linux Command Line & Bash Scripting Mastery?

Sì. Ogni lezione Linux Command Line & Bash Scripting Mastery include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Prevenire l'iniezione di comandi e argomenti
  2. Gestire i segreti in sicurezza e mantenere pulito l'ambiente
  3. Esecuzione con privilegi minimi e disciplina nell'uso di sudo
  4. Analisi statica e audit con ShellCheck
← Torna a Linux Command Line & Bash Scripting Mastery