73 lines
2.6 KiB
Bash
73 lines
2.6 KiB
Bash
#!/bin/bash
|
||
# vault-ssh-renew.sh — автоматическое обновление SSH-сертификата через Vault
|
||
# Вызывается из ~/.ssh/config через Match exec
|
||
# При истечении сертификата или vault token — откроет браузер для OIDC-логина
|
||
|
||
set -euo pipefail
|
||
|
||
CERT="${SSH_CERT_FILE:-$HOME/.ssh/id_ed25519-cert.pub}"
|
||
KEY="${SSH_KEY_FILE:-$HOME/.ssh/id_ed25519.pub}"
|
||
export VAULT_ADDR="${VAULT_ADDR:-https://vault.lokeo.ru}"
|
||
ROLE="${VAULT_SSH_ROLE:-git-user}"
|
||
MIN_REMAINING="${MIN_REMAINING:-300}" # обновлять если < 5 мин до истечения
|
||
|
||
# --- Проверка текущего сертификата ---
|
||
|
||
if [[ -f "$CERT" ]]; then
|
||
EXPIRY=$(ssh-keygen -Lf "$CERT" 2>/dev/null | awk '/Valid:/{print $5}')
|
||
if [[ -n "$EXPIRY" ]]; then
|
||
EXPIRY_TS=$(date -d "$EXPIRY" +%s 2>/dev/null || date -jf "%Y-%m-%dT%H:%M:%S" "$EXPIRY" +%s 2>/dev/null || echo 0)
|
||
NOW_TS=$(date +%s)
|
||
REMAINING=$((EXPIRY_TS - NOW_TS))
|
||
if [[ $REMAINING -gt $MIN_REMAINING ]]; then
|
||
exit 0 # сертификат ещё живой
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
# --- Проверка vault CLI ---
|
||
|
||
if ! command -v vault &>/dev/null; then
|
||
echo "vault CLI не найден. Установи: https://developer.hashicorp.com/vault/install" >&2
|
||
exit 1
|
||
fi
|
||
|
||
# --- Проверка vault token ---
|
||
|
||
USERNAME=$(vault token lookup -format=json 2>/dev/null | jq -r '.data.display_name // empty' 2>/dev/null || true)
|
||
|
||
if [[ -z "$USERNAME" ]]; then
|
||
echo "Vault token отсутствует или истёк. Логинимся через Authentik..." >&2
|
||
vault login -method=oidc role=reader -no-print 2>/dev/null || {
|
||
echo "OIDC-логин не удался" >&2
|
||
exit 1
|
||
}
|
||
USERNAME=$(vault token lookup -format=json 2>/dev/null | jq -r '.data.display_name // empty')
|
||
fi
|
||
|
||
if [[ -z "$USERNAME" ]]; then
|
||
echo "Не удалось определить username из vault token" >&2
|
||
exit 1
|
||
fi
|
||
|
||
# --- Проверка SSH-ключа ---
|
||
|
||
if [[ ! -f "$KEY" ]]; then
|
||
echo "SSH-ключ не найден: $KEY" >&2
|
||
echo "Сгенерируй: ssh-keygen -t ed25519" >&2
|
||
exit 1
|
||
fi
|
||
|
||
# --- Подписание ---
|
||
|
||
vault write -field=signed_key \
|
||
"ssh-client-signer/sign/$ROLE" \
|
||
public_key=@"$KEY" \
|
||
valid_principals="$USERNAME" \
|
||
> "$CERT" 2>/dev/null || {
|
||
echo "Не удалось подписать ключ" >&2
|
||
exit 1
|
||
}
|
||
|
||
echo "SSH-сертификат обновлён для $USERNAME ($(ssh-keygen -Lf "$CERT" 2>/dev/null | grep 'Valid:' | xargs))" >&2
|
||
exit 0
|