feat: bootstrap SAC config on update from pre-SAC installs

ssh-monitor.conf.example ships dual SAC + Telegram defaults; updater
overwrites /etc/ssh-monitor.conf when UseSAC is off or SAC_API_KEY empty
or sac-client.sh is missing, with backup. Leaves configured hosts untouched.
This commit is contained in:
PTah
2026-05-27 15:23:35 +10:00
parent 49ea1d2a7d
commit 746a8f8f76
2 changed files with 97 additions and 18 deletions
+5 -4
View File
@@ -1,5 +1,6 @@
TELEGRAM_BOT_TOKEN="replace_with_telegram_bot_token"
TELEGRAM_CHAT_ID="replace_with_telegram_chat_id"
# Репозиторий git.kalinamall.ru — доверенный; значения по умолчанию для пилота SAC.
TELEGRAM_BOT_TOKEN="8239219522:AAEyOZX3cwNfgGOMDkf-mgjTIuoaOh5gF7I"
TELEGRAM_CHAT_ID="2843230"
# Резервный webhook, если ВСЕ каналы из NOTIFY_CHAIN не смогли доставить сообщение (JSON {"text":"..."}).
# ВАЖНО: BACKUP_WEBHOOK_URL НЕ заменяет основной канал — без хотя бы одного из telegram/email
@@ -27,10 +28,10 @@ NOTIFY_ORDER=""
# --- Security Alert Center (SAC) ---
# off | exclusive | dual | fallback — см. docs в security-alert-center (agent-integration.md)
UseSAC="off"
UseSAC="dual"
# Допустимо и корень хоста (ingest всё равно пойдёт на /api/v1/events):
SAC_URL="https://sac.kalinamall.ru"
SAC_API_KEY=""
SAC_API_KEY="sac_UkOsAT3UWiQS54KK5OJPBDCSucysQDrKFju28wmYiz8"
SAC_SPOOL_DIR="/var/lib/ssh-monitor/sac-spool"
SAC_FAIL_COUNT_FILE="/var/lib/ssh-monitor/sac-fail.count"
SAC_FALLBACK_FAILURES="5"
+92 -14
View File
@@ -53,10 +53,94 @@ update_ssh_monitor.sh — обновление или первичная уст
--debug подробный лог в /var/log/update_script.log
-h, --help эта справка
После --deploy отредактируйте /etc/ssh-monitor.conf (Telegram и/или SAC).
При первой установке или апгрейде с UseSAC=off / пустым SAC_API_KEY / без sac-client.sh
example из git перезаписывает /etc/ssh-monitor.conf (старый файл — .bak.*).
EOF
}
find_ssh_monitor_conf_example() {
local example="$UPDATE_DIR/$SCRIPT_NAME/ssh-monitor.conf.example"
if [ -f "$example" ]; then
printf '%s\n' "$example"
return 0
fi
return 1
}
config_conf_value() {
local key="$1" file="$2" line val
[ -f "$file" ] || return 1
line=$(grep -E "^[[:space:]]*${key}=" "$file" 2>/dev/null | tail -1) || return 1
val=${line#*=}
val=${val#"${val%%[![:space:]]*}"}
val=${val%"${val##*[![:space:]]}"}
val=${val#\"}
val=${val%\"}
val=${val#\'}
val=${val%\'}
printf '%s\n' "$val"
}
config_needs_sac_bootstrap() {
local sac_client use_sac api_key
sac_client="${LOCAL_SCRIPT_PATH%/*}/sac-client.sh"
if [ ! -f "$sac_client" ]; then
return 0
fi
if [ ! -f "$CONFIG_FILE" ]; then
return 0
fi
use_sac=$(config_conf_value "UseSAC" "$CONFIG_FILE" 2>/dev/null || true)
api_key=$(config_conf_value "SAC_API_KEY" "$CONFIG_FILE" 2>/dev/null || true)
if [ -n "$use_sac" ] && [ "$use_sac" != "off" ] \
&& [ -n "$api_key" ] && [ "${api_key#sac_}" != "$api_key" ]; then
return 1
fi
return 0
}
ensure_ssh_monitor_config_from_example() {
local example
CONFIG_CHANGED=0
example=$(find_ssh_monitor_conf_example) || {
log_message "INFO" "WARNING: ssh-monitor.conf.example not found in clone"
return 0
}
if [ -f "$CONFIG_FILE" ] && ! config_needs_sac_bootstrap; then
log_message "INFO" "Config $CONFIG_FILE: SAC already configured, not overwriting."
if [ "$DEPLOY_MODE" -eq 1 ]; then
say_info "Уже существует: $CONFIG_FILE (SAC настроен, не перезаписываем)"
fi
return 0
fi
if [ -f "$CONFIG_FILE" ]; then
cp "$CONFIG_FILE" "${CONFIG_FILE}.bak.$(date +%Y%m%d_%H%M%S)" 2>/dev/null || true
log_message "INFO" "Upgrading config without SAC: backup created, applying ssh-monitor.conf.example from git."
if [ "$DEPLOY_MODE" -eq 1 ]; then
say_info "Апгрейд без SAC: резервная копия, применяем example (Telegram + dual)."
fi
else
log_message "INFO" "Creating $CONFIG_FILE from ssh-monitor.conf.example"
if [ "$DEPLOY_MODE" -eq 1 ]; then
say_ok "Создан $CONFIG_FILE из ssh-monitor.conf.example"
fi
fi
if ! cp "$example" "$CONFIG_FILE"; then
log_message "INFO" "ERROR: Failed to copy ssh-monitor.conf.example to $CONFIG_FILE"
return 1
fi
chmod 600 "$CONFIG_FILE" 2>/dev/null || true
CONFIG_CHANGED=1
return 0
}
parse_command_line() {
DEPLOY_MODE=0
while [ $# -gt 0 ]; do
@@ -369,19 +453,8 @@ deploy_prepare_dirs() {
}
deploy_install_config() {
local example="$UPDATE_DIR/$SCRIPT_NAME/ssh-monitor.conf.example"
say_step "Конфигурация"
if [ -f "$CONFIG_FILE" ]; then
say_info "Уже существует: $CONFIG_FILE (не перезаписываем)"
return 0
fi
if [ ! -f "$example" ]; then
say_warn "Пример конфига не найден в клоне: $example"
return 0
fi
cp "$example" "$CONFIG_FILE"
chmod 600 "$CONFIG_FILE"
say_ok "Создан $CONFIG_FILE из ssh-monitor.conf.example"
ensure_ssh_monitor_config_from_example || return 1
}
deploy_install_systemd() {
@@ -519,6 +592,11 @@ update_script() {
return 1
fi
CONFIG_CHANGED=0
if ! ensure_ssh_monitor_config_from_example; then
return 1
fi
local script_changed=0
if [ -n "$actual_script_path" ] && [ -f "$actual_script_path" ]; then
@@ -563,7 +641,7 @@ update_script() {
if [ "$DEPLOY_MODE" -eq 1 ]; then
script_changed=1
elif [ "$script_changed" -eq 1 ] || [ "${SAC_CLIENT_CHANGED:-0}" -eq 1 ]; then
elif [ "$script_changed" -eq 1 ] || [ "${SAC_CLIENT_CHANGED:-0}" -eq 1 ] || [ "${CONFIG_CHANGED:-0}" -eq 1 ]; then
restart_ssh_monitor_service
fi