This commit is contained in:
2026-02-22 00:23:30 +01:00
parent 7238579d9c
commit 084a483cf2
6 changed files with 450 additions and 32 deletions

View File

@@ -0,0 +1,205 @@
#!/usr/bin/env bash
#
# encrypt-vault-strings-to-file.sh
#
# Gegenstück zu deinem Decrypt-Script.
#
# Funktionen:
# 1. Komplettes File mit ansible-vault encrypt verschlüsseln
# 2. YAML-Datei mit key: value Zeilen in key: !vault | Blöcke umwandeln
# 3. Einzelnen String verschlüsseln (Argument, Pipe oder interaktiv)
#
# Vault-Passwortdatei: ~/.vault-pass
#
set -euo pipefail
VAULT_PASS_FILE="${HOME}/.vault-pass"
########################################
# Hilfe anzeigen
########################################
show_help() {
cat <<EOF
Usage:
$(basename "$0") [OPTION] [INPUT]
Modes:
1) File encrypt (in-place):
$(basename "$0") secrets.txt
2) YAML file (key: value → !vault block):
$(basename "$0") vars.yml
$(basename "$0") -o output.yml vars.yml
3) String encrypt:
$(basename "$0") 'mySecret'
echo 'mySecret' | $(basename "$0")
$(basename "$0") (interactive mode)
Options:
-o FILE Write YAML output to FILE instead of stdout
-h, --help Show this help and exit
Notes:
- Vault password file: ${VAULT_PASS_FILE}
- Simple "key: value" YAML lines will be converted.
- Already encrypted (!vault) entries are preserved.
- Full vault-encrypted files (ANSIBLE_VAULT header) are detected.
EOF
}
########################################
# Hauptfunktion
########################################
vencr() {
unset IFS
# --- Help Flag ---
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
show_help
exit 0
fi
# Prüfen ob Vault-Passwortdatei existiert
if [[ ! -r "$VAULT_PASS_FILE" ]]; then
echo "Vault password file not readable: $VAULT_PASS_FILE" >&2
exit 1
fi
########################################
# Optionales Output-File (-o)
########################################
local out_file=""
if [[ "${1:-}" == "-o" && -n "${2:-}" ]]; then
out_file="$2"
shift 2
fi
########################################
# --- 1) File als Argument ---
########################################
if [[ -n "${1:-}" && -f "$1" ]]; then
local f="$1"
# Fall A: Datei ist bereits vollständig vault-verschlüsselt
if [[ "$(head -n1 "$f")" == "\$ANSIBLE_VAULT;1.1;AES256"* ]]; then
echo "File already encrypted (ANSIBLE_VAULT header found): $f" >&2
return 0
fi
# Fall B: YAML mit key: value Zeilen
if grep -Eq '^[[:space:]]*[A-Za-z0-9_.-]+:[[:space:]]*[^#].*$' "$f"; then
local tmpout
tmpout="$(mktemp)"
# Datei zeilenweise lesen
while IFS= read -r line || [[ -n "$line" ]]; do
# Leere Zeilen oder Kommentare unverändert übernehmen
if [[ -z "$line" || "$line" =~ ^[[:space:]]*# ]]; then
printf '%s\n' "$line" >> "$tmpout"
continue
fi
# Bereits verschlüsselte !vault Einträge nicht verändern
if echo "$line" | grep -q '\!vault'; then
printf '%s\n' "$line" >> "$tmpout"
continue
fi
# Einfache key: value Zeilen erkennen
if [[ "$line" =~ ^([[:space:]]*)([A-Za-z0-9_.-]+):[[:space:]]*(.+)$ ]]; then
local indent="${BASH_REMATCH[1]}"
local key="${BASH_REMATCH[2]}"
local value="${BASH_REMATCH[3]}"
# YAML-Blockindikatoren nicht verändern
if [[ "$value" == "|" || "$value" == ">" || "$value" == "" ]]; then
printf '%s\n' "$line" >> "$tmpout"
continue
fi
# Leichte Bereinigung von Quotes
value="${value%\"}"; value="${value#\"}"
value="${value%\'}"; value="${value#\'}"
# Verschlüsselung via ansible-vault encrypt_string
while IFS= read -r enc_line; do
printf '%s%s\n' "$indent" "$enc_line" >> "$tmpout"
done < <(
printf '%s' "$value" |
ansible-vault encrypt_string \
--stdin-name "$key" \
--vault-password-file "$VAULT_PASS_FILE"
)
else
# Nicht passende Zeilen unverändert übernehmen
printf '%s\n' "$line" >> "$tmpout"
fi
done < "$f"
# Output schreiben
if [[ -n "$out_file" ]]; then
mv "$tmpout" "$out_file"
echo "Encrypted YAML written to: $out_file" >&2
else
cat "$tmpout"
rm -f "$tmpout"
fi
return 0
fi
# Fall C: Normale Datei → komplett verschlüsseln (in-place)
ansible-vault encrypt \
--vault-password-file "$VAULT_PASS_FILE" \
"$f"
echo "Encrypted file in-place: $f" >&2
return 0
fi
########################################
# --- 2) String-Verschlüsselung ---
########################################
local str=""
local name="secret"
# String als Argument
if [[ -n "${1:-}" ]]; then
str="$1"
# String via Pipe
elif [[ ! -t 0 ]]; then
str="$(cat)"
# Interaktiver Modus
else
echo "Interactive mode."
read -r -p "Variable name (default: secret): " name_in
if [[ -n "$name_in" ]]; then
name="$name_in"
fi
echo "Paste plaintext and press Ctrl-D to confirm:"
str="$(cat)"
echo
fi
# Ausgabe als YAML-kompatibler !vault Block
printf '%s' "$str" |
ansible-vault encrypt_string \
--stdin-name "$name" \
--vault-password-file "$VAULT_PASS_FILE"
}
########################################
# Script starten
########################################
vencr "$@"