417 lines
16 KiB
Bash
Executable file
417 lines
16 KiB
Bash
Executable file
#!/usr/bin/env bash
|
||
set -Eeuo pipefail
|
||
# setup-vault-agent-proxy-config-v4.9.sh
|
||
# Datum: 2025-10-02
|
||
#
|
||
# ========================= FEATURE MANIFEST (Proxy v4.9) ======================
|
||
# 🔒 Auth-Optionen
|
||
# 1) **Default: auth/cert (mTLS)** — erwartet, dass dein mTLS-Client-Script
|
||
# (setup-vault-agent-mtls-client-config-*.sh) zuvor für **--app <app>**
|
||
# gelaufen ist und unter ~/<user>/vault/mtls/agent.{crt,key} existieren.
|
||
# • Strikter CN-Check (Standard an) gegen ^agent-<app>(-[a-z0-9]+)?\.<env>\.privsec\.ch$
|
||
# 2) **Alternative: AppRole** — mit --auth approle wird eine eigene AppRole
|
||
# (<app>-pki-ca) erstellt und role_id/secret_id im Agent-Verzeichnis hinterlegt.
|
||
#
|
||
# 📦 YAML/Config
|
||
# 3) Liest ./config/apps.yaml und verwendet:
|
||
# environments.{vault_addr, vault_sni, pki_mount, tls_dir,
|
||
# proxy{user,chain_path,reload}}
|
||
# apps[].{name, proxy_user?, proxy_chain_path?, proxy_reload?, cert_map_name?}
|
||
#
|
||
# 🧩 Aufgabe dieses Agents
|
||
# 4) Periodisch **ISSUING CA (Intermediate)** aus ${PKI_MOUNT}/cert/ca lesen,
|
||
# mit **Root** zu einer **Kette** kombinieren und nach proxy.chain_path schreiben.
|
||
# 5) Post-Hook `vault-agent-post-chain.sh` triggert Reload via Label (z. B. podman).
|
||
#
|
||
# 🔐 Policies & Rollen
|
||
# 6) Erstellt/aktualisiert Policy **pki-ca-read-<app>** (Read auf <pki_mount>/cert/ca & Renew-Self).
|
||
# 7) Für **--auth approle** zusätzlich **pki-ca-bootstrap-<app>** (Role-/Secret-ID).
|
||
# 8) **v4.8/4.9 bei auth/cert**:
|
||
# • Cert-Mapping **auth/cert/certs/<mapping>** wird **automatisch** um
|
||
# Policy **pki-ca-read-<app>** erweitert (idempotent).
|
||
# – Mapping-Name: apps[].cert_map_name oder Default **agent-<app>**
|
||
# – Bestehende Policies (z. B. pki-issue-<app>, marker-cert-auth) bleiben erhalten.
|
||
#
|
||
# 🌐 TLS ggü. Vault (Server-Verify)
|
||
# 9) vault { ca_cert = <Root-Kopie> ; tls_server_name = <vault_sni> }
|
||
# • Root-Kopie wird aus <tls_dir>/root_ca.pem gespiegelt nach ~/<user>/vault/ca/ca.pem.
|
||
# – tls_dir kommt aus YAML (environments.<env>.tls_dir),
|
||
# Fallback: /home/vault/tls-<env>
|
||
#
|
||
# 🧰 Verzeichnisse/Dateien
|
||
# 10) Agent unter ~/<user>/.vault-agent-<app>-ca/{vault-agent.hcl, ca.tpl, token, bin/...}
|
||
# Kette nach proxy.chain_path (z. B. /home/proxytest/nginx/ca/current-ca-chain.pem)
|
||
#
|
||
# ⚙️ Systemd (user)
|
||
# 11) Legt **~/.config/systemd/user/vault-agent-<app>-ca.service** an und enabled/started ihn.
|
||
#
|
||
# 🆕 v4.7/4.8/4.9 Additiv (bestehendes Verhalten unverändert)
|
||
# 12) **Force-Restart** nach Setup → sofort neues Token & frisches Rendering (analog App-Script).
|
||
# 13) **CLI-Token-Symlink** ~/.vault-token → konsistente CLI wie beim App-Agent.
|
||
# 14) **Kurze Statusausgabe** direkt nach dem Restart (ohne Pager).
|
||
# 15) Am Ende Hinweise: Logs & TLS-Verify.
|
||
# =============================================================================
|
||
#
|
||
# Exit-Codes: 2=Args/Config; 3=Linux-User fehlt; 4=Post-Hook fehlt; 5=mTLS fehlt/ungenügend
|
||
|
||
# ===== Pretty logs =====
|
||
if [[ -t 1 ]]; then B=$'\e[1m'; R=$'\e[0m'; BL=$'\e[34m'; G=$'\e[32m'; Y=$'\e[33m'; E=$'\e[31m'; else B= R= BL= G= Y= E=; fi
|
||
ts(){ date +"%Y-%m-%d %H:%M:%S"; }
|
||
info(){ echo -e "🟦 ${BL}${B}[$(ts)]${R} $*"; }
|
||
ok(){ echo -e "🟩 ${G}${B}[$(ts)]${R} $*"; }
|
||
warn(){ echo -e "🟨 ${Y}${B}[$(ts)]${R} $*"; }
|
||
err(){ echo -e "🟥 ${E}${B}[$(ts)]${R} $*" >&2; }
|
||
|
||
# ===== Needs =====
|
||
need(){ command -v "$1" >/dev/null || { err "missing: $1"; exit 2; }; }
|
||
|
||
# ===== Defaults / Args =====
|
||
: "${LOG_LEVEL:=info}"
|
||
: "${DEFAULT_ENV:=test}"
|
||
: "${DEFAULT_CONFIG:=./config/apps.yaml}"
|
||
: "${STRICT_CN_CHECK:=1}"
|
||
|
||
ENV_NAME="$DEFAULT_ENV"; CFG="$DEFAULT_CONFIG"; APPN=""; AUTH_METHOD="cert" # cert|approle
|
||
TLS_SNI_OVERRIDE=""; CHAIN_PATH_OVERRIDE=""; RELOAD_LABEL_OVERRIDE=""
|
||
|
||
usage(){ sed -n '1,260p' "$0"; exit 2; }
|
||
|
||
while [[ $# -gt 0 ]]; do
|
||
case "$1" in
|
||
--env) ENV_NAME="$2"; shift 2;;
|
||
--config) CFG="$2"; shift 2;;
|
||
--app) APPN="$2"; shift 2;;
|
||
--auth) AUTH_METHOD="$2"; shift 2;;
|
||
--tls-server-name) TLS_SNI_OVERRIDE="$2"; shift 2;;
|
||
--chain-path) CHAIN_PATH_OVERRIDE="$2"; shift 2;;
|
||
--reload-label) RELOAD_LABEL_OVERRIDE="$2"; shift 2;;
|
||
-h|--help) usage;;
|
||
*) err "unknown arg: $1"; usage;;
|
||
esac
|
||
done
|
||
[[ -n "$APPN" ]] || { err "--app ist erforderlich"; exit 2; }
|
||
case "$AUTH_METHOD" in cert|approle) ;; * ) err "--auth muss cert|approle sein"; exit 2;; esac
|
||
|
||
# ===== Binaries =====
|
||
need vault; need jq; need python3; need install; need systemctl; need getent; need openssl
|
||
|
||
# ===== YAML laden =====
|
||
CFG_ABS="$(readlink -f -- "$CFG")" || { err "cannot resolve $CFG"; exit 2; }
|
||
CFGJSON="$(python3 - "$CFG_ABS" <<'PY'
|
||
import yaml, json, sys, io
|
||
p = sys.argv[1]
|
||
with io.open(p, "r", encoding="utf-8") as f:
|
||
print(json.dumps(yaml.safe_load(f)))
|
||
PY
|
||
)" || { err "YAML parse failed: $CFG_ABS"; exit 2; }
|
||
|
||
jqenv(){ echo "$CFGJSON" | jq -r ".environments.\"$ENV_NAME\"$1"; }
|
||
jqapp(){ echo "$CFGJSON" | jq -r ".apps[] | select(.name==\"$APPN\")$1"; }
|
||
|
||
VAULT_ADDR="$(jqenv '.vault_addr')"
|
||
PKI_MOUNT="$(jqenv '.pki_mount')"
|
||
|
||
# v4.9: TLS-SNI + TLS-DIR aus YAML (mit Fallback)
|
||
VAULT_SNI_ENV="$(jqenv '.vault_sni')"
|
||
[[ "$VAULT_SNI_ENV" == "null" || -z "$VAULT_SNI_ENV" ]] && VAULT_SNI_ENV="vault.${ENV_NAME}.privsec.ch"
|
||
TLS_SNI="${TLS_SNI_OVERRIDE:-$VAULT_SNI_ENV}"
|
||
|
||
TLS_DIR_ENV="$(jqenv '.tls_dir')"
|
||
if [[ -n "$TLS_DIR_ENV" && "$TLS_DIR_ENV" != "null" ]]; then
|
||
TLS_DIR="${TLS_DIR_ENV%/}"
|
||
else
|
||
TLS_DIR="/home/vault/tls-${ENV_NAME}"
|
||
fi
|
||
ROOT_SRC="${TLS_DIR}/root_ca.pem"
|
||
|
||
[[ "$VAULT_ADDR" != "null" && "$PKI_MOUNT" != "null" ]] || { err "incomplete env config: vault_addr/pki_mount"; exit 2; }
|
||
|
||
PROXY_USER_DEF="$(jqenv '.proxy.user')"
|
||
CHAIN_PATH_DEF="$(jqenv '.proxy.chain_path')"
|
||
RELOAD_DEF="$(jqenv '.proxy.reload')"
|
||
|
||
PROXY_USER_APP="$(jqapp '.proxy_user')"
|
||
CHAIN_PATH_APP="$(jqapp '.proxy_chain_path')"
|
||
RELOAD_APP="$(jqapp '.proxy_reload')"
|
||
CERT_MAP_NAME_YAML="$(jqapp '.cert_map_name')"
|
||
|
||
PROXY_USER="$PROXY_USER_DEF"; [[ "$PROXY_USER_APP" != "null" ]] && PROXY_USER="$PROXY_USER_APP"
|
||
[[ -n "$PROXY_USER" && "$PROXY_USER" != "null" ]] || { err "proxy.user fehlt in YAML"; exit 2; }
|
||
|
||
CHAIN_PATH="$CHAIN_PATH_DEF"; [[ "$CHAIN_PATH_APP" != "null" ]] && CHAIN_PATH="$CHAIN_PATH_APP"
|
||
[[ -n "$CHAIN_PATH_OVERRIDE" ]] && CHAIN_PATH="$CHAIN_PATH_OVERRIDE"
|
||
[[ -n "$CHAIN_PATH" && "$CHAIN_PATH" != "null" ]] || { err "proxy.chain_path fehlt in YAML/CLI"; exit 2; }
|
||
|
||
RELOAD_LABEL="${RELOAD_APP:-$RELOAD_DEF}"
|
||
[[ "$RELOAD_LABEL" == "null" || -z "$RELOAD_LABEL" ]] && RELOAD_LABEL="tls=true"
|
||
TLS_SNI="${TLS_SNI_OVERRIDE:-$TLS_SNI}" # falls Flag gesetzt, override YAML
|
||
|
||
# Cert-Mapping-Name: YAML (cert_map_name) oder Default agent-<app>
|
||
CERT_MAPPING="agent-${APPN}"
|
||
if [[ -n "$CERT_MAP_NAME_YAML" && "$CERT_MAP_NAME_YAML" != "null" ]]; then
|
||
CERT_MAPPING="$CERT_MAP_NAME_YAML"
|
||
fi
|
||
|
||
export VAULT_ADDR
|
||
|
||
info "ENV=${ENV_NAME} VAULT_ADDR=${VAULT_ADDR}"
|
||
info "TLS_SNI=${TLS_SNI}"
|
||
info "TLS_DIR=${TLS_DIR} ROOT_SRC=${ROOT_SRC}"
|
||
info "CERT_MAPPING=auth/cert/certs/${CERT_MAPPING}"
|
||
|
||
# ===== Helfer für Policies am Cert-Mapping =====
|
||
merge_policies(){
|
||
local json="$1"
|
||
printf '%s' "$json" | jq -r '
|
||
def to_arr(x):
|
||
if x == null then []
|
||
elif (x|type)=="string" then (x|split(",")|map(gsub("\\s+";""))|map(select(length>0)))
|
||
else x
|
||
end;
|
||
.data as $d
|
||
| ((to_arr($d.policies) + to_arr($d.token_policies)) | unique)
|
||
| join(",")
|
||
'
|
||
}
|
||
|
||
ensure_cert_mapping_has_policy(){
|
||
local mapping="$1" pol="$2"
|
||
local j
|
||
if ! j="$(vault read -format=json "auth/cert/certs/${mapping}")"; then
|
||
warn "Cert-Mapping nicht gefunden: auth/cert/certs/${mapping} – Policy ${pol} kann nicht angehängt werden"
|
||
return 0
|
||
fi
|
||
|
||
local merged
|
||
merged="$(merge_policies "$j")"
|
||
if [[ -z "$merged" ]]; then
|
||
merged="$pol"
|
||
elif grep -q -E "(^|,)${pol}(,|$)" <<<"$merged"; then
|
||
info "Cert-Mapping ${mapping}: Policy ${pol} bereits vorhanden"
|
||
return 0
|
||
else
|
||
merged="${merged},${pol}"
|
||
fi
|
||
|
||
# Zertifikat & allowed_common_names auslesen, damit wir sie beim write nicht verlieren
|
||
local crt allowed tmp
|
||
crt="$(printf '%s' "$j" | jq -r '.data.certificate // ""')"
|
||
allowed="$(printf '%s' "$j" | jq -r '(.data.allowed_common_names // []) | join(",")')"
|
||
|
||
if [[ -n "$crt" ]]; then
|
||
tmp="$(mktemp)"
|
||
printf '%s\n' "$crt" > "$tmp"
|
||
if [[ -n "$allowed" ]]; then
|
||
vault write "auth/cert/certs/${mapping}" \
|
||
certificate=@"$tmp" \
|
||
allowed_common_names="${allowed}" \
|
||
policies="${merged}" token_policies="${merged}" >/dev/null
|
||
else
|
||
vault write "auth/cert/certs/${mapping}" \
|
||
certificate=@"$tmp" \
|
||
policies="${merged}" token_policies="${merged}" >/dev/null
|
||
fi
|
||
rm -f "$tmp"
|
||
else
|
||
vault write "auth/cert/certs/${mapping}" \
|
||
policies="${merged}" token_policies="${merged}" >/dev/null
|
||
fi
|
||
|
||
ok "Cert-Mapping aktualisiert: auth/cert/certs/${mapping} (Policies: ${merged})"
|
||
}
|
||
|
||
# ===== User/Dirs/Paths =====
|
||
id -u "$PROXY_USER" >/dev/null 2>&1 || { err "Linux-User $PROXY_USER fehlt"; exit 3; }
|
||
HOME_DIR="/home/${PROXY_USER}"
|
||
AGENT_DIR="${HOME_DIR}/.vault-agent-${APPN}-ca"
|
||
RID="${AGENT_DIR}/role_id"; SID="${AGENT_DIR}/secret_id"; TOKEN_FILE="${AGENT_DIR}/token"
|
||
BIN_DIR="${AGENT_DIR}/bin"; POST_LOCAL="${BIN_DIR}/vault-agent-post-chain.sh"
|
||
UNIT="${HOME_DIR}/.config/systemd/user/vault-agent-${APPN}-ca.service"
|
||
|
||
# Trust (für Server-Verify): Root aus TLS_DIR spiegeln
|
||
CA_DIR="${HOME_DIR}/vault/ca"; CA_FILE="${CA_DIR}/ca.pem"
|
||
|
||
# ===== Ensure dirs & copy Root =====
|
||
sudo install -d -m 0700 -o "$PROXY_USER" -g "$PROXY_USER" "$AGENT_DIR"
|
||
sudo install -d -m 0755 -o "$PROXY_USER" -g "$PROXY_USER" "$BIN_DIR"
|
||
sudo install -d -m 0755 -o "$PROXY_USER" -g "$PROXY_USER" "$(dirname "$CHAIN_PATH")"
|
||
sudo install -d -m 0755 -o "$PROXY_USER" -g "$PROXY_USER" "$CA_DIR"
|
||
|
||
if [[ -r "$ROOT_SRC" ]]; then
|
||
sudo install -D -m 0644 -o "$PROXY_USER" -g "$PROXY_USER" "$ROOT_SRC" "$CA_FILE"
|
||
ok "Root CA gespiegelt → $CA_FILE (Quelle: $ROOT_SRC)"
|
||
else
|
||
warn "Root nicht gefunden: $ROOT_SRC → trage später manuell nach $CA_FILE ein"
|
||
fi
|
||
|
||
# ===== Policies =====
|
||
CA_POLICY_NAME="pki-ca-read-${APPN}"
|
||
TMP="$(mktemp)"
|
||
cat >"$TMP" <<EOF
|
||
path "$PKI_MOUNT/cert/ca" { capabilities=["read"] }
|
||
path "auth/token/renew-self" { capabilities=["update"] }
|
||
EOF
|
||
vault policy write "${CA_POLICY_NAME}" "$TMP" >/dev/null || true
|
||
|
||
# v4.8/4.9: Cert-Mapping automatisch um CA-Policy erweitern (idempotent)
|
||
if [[ -n "$CERT_MAPPING" ]]; then
|
||
info "Cert-Mapping check → auth/cert/certs/${CERT_MAPPING} (+${CA_POLICY_NAME})"
|
||
ensure_cert_mapping_has_policy "$CERT_MAPPING" "$CA_POLICY_NAME" || true
|
||
fi
|
||
|
||
cat >"$TMP" <<EOF
|
||
path "auth/approle/role/${APPN}-pki-ca/role-id" { capabilities=["read"] }
|
||
path "auth/approle/role/${APPN}-pki-ca/secret-id" { capabilities=["create","update"] }
|
||
EOF
|
||
vault policy write "pki-ca-bootstrap-${APPN}" "$TMP" >/dev/null || true
|
||
rm -f "$TMP"
|
||
|
||
# ===== Auth: cert (strict) oder approle =====
|
||
AUTO_AUTH_BLOCK=""
|
||
TLS_EXTRA=$'\n tls_server_name = "'"${TLS_SNI}"$'"\n'
|
||
|
||
if [[ "$AUTH_METHOD" == "cert" ]]; then
|
||
MTLS_DIR="${HOME_DIR}/vault/mtls"
|
||
CRT="${MTLS_DIR}/agent.crt"; KEY="${MTLS_DIR}/agent.key"
|
||
if ! ( sudo -u "$PROXY_USER" test -s "$CRT" && sudo -u "$PROXY_USER" test -s "$KEY" ); then
|
||
err "Auth=cert gefordert, aber mTLS fehlt: ${MTLS_DIR}/agent.{crt,key}"; exit 5
|
||
fi
|
||
# Strikter CN-Check
|
||
CN_ACT="$(openssl x509 -in "$CRT" -noout -subject -nameopt RFC2253 | sed -n 's/^subject=//; s/.*CN=\([^,]*\).*/\1/p')"
|
||
EXP_RE="^agent-${APPN}(-[a-z0-9]+)?\\.${ENV_NAME}\\.privsec\\.ch$"
|
||
if [[ "$STRICT_CN_CHECK" == "1" ]]; then
|
||
if ! [[ "$CN_ACT" =~ $EXP_RE ]]; then
|
||
err "mTLS CN '$CN_ACT' passt nicht zu $EXP_RE"; exit 5
|
||
else
|
||
ok "mTLS CN ok: $CN_ACT"
|
||
fi
|
||
else
|
||
[[ "$CN_ACT" =~ $EXP_RE ]] && info "CN passt (tolerant)" || warn "CN abweichend (tolerant)"
|
||
fi
|
||
TLS_EXTRA+=$' client_cert = "'"${CRT}"$'"\n'
|
||
TLS_EXTRA+=$' client_key = "'"${KEY}"$'"\n'
|
||
AUTO_AUTH_BLOCK=$(cat <<'EOF'
|
||
auto_auth {
|
||
method "cert" { }
|
||
sink "file" { config = { path = "__TOKEN_FILE__", mode = 0400 } }
|
||
}
|
||
EOF
|
||
)
|
||
else
|
||
export VAULT_TOKEN="${VAULT_ADMIN_TOKEN:-${VAULT_TOKEN:-}}"
|
||
: "${VAULT_TOKEN:?VAULT_TOKEN oder VAULT_ADMIN_TOKEN erforderlich für --auth approle}"
|
||
vault auth enable approle >/dev/null 2>&1 || true
|
||
vault write "auth/approle/role/${APPN}-pki-ca" \
|
||
policies="${CA_POLICY_NAME}" bind_secret_id=true \
|
||
token_type=service token_period=24h secret_id_ttl=0 secret_id_num_uses=0 >/dev/null
|
||
RID_VAL="$(vault read -field=role_id "auth/approle/role/${APPN}-pki-ca/role-id")"
|
||
SID_VAL="$(vault write -f -field=secret_id "auth/approle/role/${APPN}-pki-ca/secret-id")"
|
||
sudo bash -c "umask 077; printf '%s' '${RID_VAL}' > '${RID}'; chown ${PROXY_USER}:${PROXY_USER} '${RID}'; chmod 600 '${RID}'"
|
||
sudo bash -c "umask 077; printf '%s' '${SID_VAL}' > '${SID}'; chown ${PROXY_USER}:${PROXY_USER} '${SID}'; chmod 600 '${SID}'"
|
||
AUTO_AUTH_BLOCK=$(cat <<'EOF'
|
||
auto_auth {
|
||
method "approle" {
|
||
config = {
|
||
role_id_file_path = "__RID__"
|
||
secret_id_file_path = "__SID__"
|
||
remove_secret_id_file_after_reading = false
|
||
}
|
||
}
|
||
sink "file" { config = { path = "__TOKEN_FILE__", mode = 0400 } }
|
||
}
|
||
EOF
|
||
)
|
||
fi
|
||
|
||
# ===== HCL + Template =====
|
||
HCL_CONTENT=$(cat <<HCL
|
||
pid_file = "${AGENT_DIR}/pidfile"
|
||
|
||
vault {
|
||
address = "${VAULT_ADDR}"
|
||
ca_cert = "${CA_FILE}"${TLS_EXTRA}
|
||
}
|
||
|
||
__AUTO_AUTH__
|
||
|
||
template {
|
||
source = "${AGENT_DIR}/ca.tpl"
|
||
destination = "${AGENT_DIR}/.ca.json"
|
||
command = "CHAIN_FILE='${CHAIN_PATH}' ROOT_FILE='${CA_FILE}' RELOAD_TLS_LABEL='${RELOAD_LABEL}' ${POST_LOCAL}"
|
||
}
|
||
HCL
|
||
)
|
||
HCL_CONTENT="${HCL_CONTENT/__AUTO_AUTH__/${AUTO_AUTH_BLOCK}}"
|
||
HCL_CONTENT="${HCL_CONTENT/__TOKEN_FILE__/${TOKEN_FILE}}"
|
||
HCL_CONTENT="${HCL_CONTENT/__RID__/${RID}}"
|
||
HCL_CONTENT="${HCL_CONTENT/__SID__/${SID}}"
|
||
|
||
sudo -u "$PROXY_USER" tee "${AGENT_DIR}/vault-agent.hcl" >/dev/null <<<"$HCL_CONTENT"
|
||
|
||
sudo -u "$PROXY_USER" tee "${AGENT_DIR}/ca.tpl" >/dev/null <<TPL
|
||
{{ with secret "${PKI_MOUNT}/cert/ca" }}
|
||
{ "issuing_ca": {{ toJSON .Data.certificate }} }
|
||
{{ end }}
|
||
TPL
|
||
|
||
# ===== Post-Hook bereitstellen =====
|
||
SCRIPT_DIR="$(cd -- "$(dirname -- "$0")" && pwd)"
|
||
POST_SRC="${INFRA_DIR}/scripts/vault-agent-post-chain.sh"
|
||
if [[ -r "$POST_SRC" ]]; then
|
||
sudo /usr/bin/install -m 0755 -o "$PROXY_USER" -g "$PROXY_USER" -D "$POST_SRC" "$POST_LOCAL"
|
||
ok "post-hook installiert: ${POST_LOCAL}"
|
||
else
|
||
err "Post-Hook fehlt: $POST_SRC"; exit 4
|
||
fi
|
||
|
||
# ===== systemd (user) =====
|
||
sudo -u "$PROXY_USER" install -d -m 0755 "${HOME_DIR}/.config/systemd/user"
|
||
sudo -u "$PROXY_USER" tee "$UNIT" >/dev/null <<UNIT
|
||
[Unit]
|
||
Description=Vault Agent (${APPN}-ca) - refresh proxy CA chain (v4.9)
|
||
Wants=network-online.target
|
||
After=network-online.target
|
||
|
||
[Service]
|
||
Type=simple
|
||
WorkingDirectory=${AGENT_DIR}
|
||
Environment=VAULT_ADDR=${VAULT_ADDR}
|
||
ExecStart=/usr/bin/vault agent -log-level=${LOG_LEVEL} -config=${AGENT_DIR}/vault-agent.hcl
|
||
Restart=on-failure
|
||
RestartSec=5s
|
||
|
||
[Install]
|
||
WantedBy=default.target
|
||
UNIT
|
||
|
||
PROXY_UID="$(id -u "$PROXY_USER")"
|
||
loginctl enable-linger "$PROXY_USER" >/dev/null || true
|
||
systemctl start "user@${PROXY_UID}.service" >/dev/null || true
|
||
XDG_RUNTIME_DIR="/run/user/${PROXY_UID}"; mkdir -p "$XDG_RUNTIME_DIR"; chown "${PROXY_USER}:${PROXY_USER}" "$XDG_RUNTIME_DIR" || true
|
||
sudo -u "$PROXY_USER" XDG_RUNTIME_DIR="$XDG_RUNTIME_DIR" systemctl --user daemon-reload
|
||
sudo -u "$PROXY_USER" XDG_RUNTIME_DIR="$XDG_RUNTIME_DIR" systemctl --user enable --now "vault-agent-${APPN}-ca.service"
|
||
|
||
# Force-Restart & Status
|
||
info "service restart (erzwinge Neustart des user-services)"
|
||
sudo -u "$PROXY_USER" XDG_RUNTIME_DIR="$XDG_RUNTIME_DIR" systemctl --user restart "vault-agent-${APPN}-ca.service"
|
||
info "service status (kurz, ohne Pager)"
|
||
sudo -u "$PROXY_USER" XDG_RUNTIME_DIR="$XDG_RUNTIME_DIR" systemctl --user --no-pager --full status "vault-agent-${APPN}-ca.service" || true
|
||
|
||
# Default-CLI-Token-Symlink
|
||
sudo -u "$PROXY_USER" ln -sf "${TOKEN_FILE}" "${HOME_DIR}/.vault-token" || true
|
||
info "default CLI token symlinked → ${HOME_DIR}/.vault-token -> ${TOKEN_FILE}"
|
||
|
||
# ===== Quick result =====
|
||
if sudo -u "$PROXY_USER" test -s "$CHAIN_PATH"; then
|
||
ok "CA chain present: ${CHAIN_PATH}"
|
||
else
|
||
warn "CA chain not yet present → check: journalctl --user -u vault-agent-${APPN}-ca.service -e -n 60"
|
||
fi
|
||
|
||
cat <<OUT
|
||
|
||
Next steps / Checks:
|
||
• Logs: sudo -u ${PROXY_USER} journalctl --user -u vault-agent-${APPN}-ca.service -e -n 60
|
||
• TLS OK: openssl s_client -connect 127.0.0.1:22300 -servername ${TLS_SNI} \\
|
||
-CAfile ${CA_FILE} -brief </dev/null | sed -n '1,10p'
|
||
OUT
|