Add terminal dialogs for all enrollment choices and inputs
This commit is contained in:
+106
-7
@@ -6,14 +6,52 @@ umask 077
|
||||
|
||||
fail() { printf 'FEHLER: %s\n' "$*" >&2; exit 1; }
|
||||
say() { printf '%s\n' "$*"; }
|
||||
ask() { printf '%s ' "$1" >&2; IFS= read -r REPLY <&3 || fail 'Eingabe abgebrochen.'; }
|
||||
UI_TOOL=''; UI_HEIGHT=20; UI_WIDTH=76
|
||||
init_ui() {
|
||||
local dimensions rows=24 columns=80
|
||||
UI_TOOL=''
|
||||
if command -v whiptail >/dev/null 2>&1; then UI_TOOL=whiptail
|
||||
elif command -v dialog >/dev/null 2>&1; then UI_TOOL=dialog; fi
|
||||
dimensions=$(stty size <&3 2>/dev/null) || dimensions=''
|
||||
if [[ $dimensions =~ ^([0-9]+)[[:space:]]+([0-9]+)$ ]]; then
|
||||
rows=${BASH_REMATCH[1]}; columns=${BASH_REMATCH[2]}
|
||||
fi
|
||||
if [[ -z $UI_TOOL || ${TERM:-dumb} == dumb || $rows -lt 16 || $columns -lt 60 ]]; then
|
||||
UI_TOOL=''
|
||||
say 'Dialogoberflaeche nicht verfuegbar (whiptail/dialog oder ausreichend grosses Terminal fehlt); Texteingabe verwenden.'
|
||||
return 0
|
||||
fi
|
||||
UI_HEIGHT=$((rows-4)); UI_WIDTH=$((columns-4))
|
||||
if [[ $UI_HEIGHT -gt 30 ]]; then UI_HEIGHT=30; fi
|
||||
if [[ $UI_WIDTH -gt 110 ]]; then UI_WIDTH=110; fi
|
||||
}
|
||||
ui_capture() {
|
||||
# The UI uses the controlling terminal, even if this script's stdin is a pipe.
|
||||
# Secrets/selections are captured on a separate descriptor, never stdout/logs.
|
||||
REPLY=$("$UI_TOOL" --output-fd 4 "$@" 4>&1 1>&3 2>&3 <&3)
|
||||
}
|
||||
ask() {
|
||||
if [[ -n $UI_TOOL ]]; then
|
||||
ui_capture --title 'LXC Enrollment - Eingabe' --ok-button 'Weiter' --cancel-button 'Abbrechen' \
|
||||
--inputbox "$1" "$UI_HEIGHT" "$UI_WIDTH" "${2:-}" || fail 'Eingabe abgebrochen oder Dialog fehlgeschlagen.'
|
||||
else
|
||||
printf '%s ' "$1" >&2
|
||||
IFS= read -r REPLY <&3 || fail 'Eingabe abgebrochen.'
|
||||
fi
|
||||
}
|
||||
secret() {
|
||||
if [[ -n $UI_TOOL ]]; then
|
||||
ui_capture --title 'LXC Enrollment - Verdeckte Eingabe' --ok-button 'Weiter' --cancel-button 'Abbrechen' \
|
||||
--passwordbox "$1" "$UI_HEIGHT" "$UI_WIDTH" || fail 'Eingabe abgebrochen oder Dialog fehlgeschlagen.'
|
||||
return 0
|
||||
fi
|
||||
printf '%s ' "$1" >&2
|
||||
IFS= read -r -s REPLY <&3 || fail 'Eingabe abgebrochen.'
|
||||
printf '\n' >&2
|
||||
}
|
||||
installed_label() { if [[ $1 == 1 ]]; then printf 'vorhanden'; else printf 'fehlt'; fi; }
|
||||
choice_hint() { if [[ $1 == 1 ]]; then printf '[J/n]'; else printf '[j/N]'; fi; }
|
||||
yesno_label() { if [[ $1 == 1 ]]; then printf 'Ja'; else printf 'Nein'; fi; }
|
||||
|
||||
LIST=0; DRY=0; MANAGER=''; VERSION=''; LOGIN_SERVER=''; SELECTION=''; VERSION_EXPLICIT=0
|
||||
SSH_ENABLED=1; SSH_USER=''; SSH_SUDO=0; SSH_NOPASSWD=0; SAVE_SETTINGS=1
|
||||
@@ -45,6 +83,8 @@ Nur laufende Debian-/Ubuntu-LXCs mit systemd. Vorhandene Tailscale-/Wazuh-
|
||||
Registrierungen bleiben unveraendert. Optional Tailscale SSH/Nutzer/Sudo fuer die Auswahl.
|
||||
Lokale Einstellungen: /etc/lxc-enroll/.vars (JSON, ohne Geheimnisse).
|
||||
Keine Host-Agent-Installation. Geheimnisse werden lokal abgefragt.
|
||||
Dialogoberflaeche fuer Auswahl, Eingaben und Geheimnisse (whiptail/dialog).
|
||||
LXC-Checkliste: Leertaste markiert. Ohne Dialogwerkzeug: Texteingabe.
|
||||
HELP
|
||||
exit 0 ;;
|
||||
*) fail "Unbekannte Option: $1" ;;
|
||||
@@ -70,7 +110,20 @@ trap 'exit 130' INT
|
||||
trap 'exit 143' TERM
|
||||
|
||||
yes_no() {
|
||||
local prompt=$1 default=$2
|
||||
local prompt=$1 default=$2 rc
|
||||
local -a options=()
|
||||
if [[ -n ${UI_TOOL:-} ]]; then
|
||||
[[ $default != 0 ]] || options+=(--defaultno)
|
||||
# Keep keyboard hints only in text mode; buttons show Ja/Nein in the UI.
|
||||
prompt=${prompt% \[J/n\]}; prompt=${prompt% \[j/N\]}
|
||||
if ui_capture --title 'LXC Enrollment - Auswahl' --yes-button 'Ja' --no-button 'Nein' \
|
||||
"${options[@]}" --yesno "$prompt" "$UI_HEIGHT" "$UI_WIDTH"; then REPLY=1
|
||||
else
|
||||
rc=$?
|
||||
case "$rc" in 1) REPLY=0;; *) fail 'Auswahl abgebrochen oder Dialog fehlgeschlagen.';; esac
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
ask "$prompt"
|
||||
case "$REPLY" in '' ) REPLY=$default;; 1|j|J|ja|Ja|y|Y|yes|Yes) REPLY=1;; 0|n|N|nein|Nein|no|No) REPLY=0;; *) fail 'Bitte j oder n eingeben (auch 1/0 moeglich).';; esac
|
||||
}
|
||||
@@ -166,6 +219,36 @@ PROBE
|
||||
done
|
||||
}
|
||||
|
||||
choose_lxcs() {
|
||||
local menu_height id rc
|
||||
local -a items=()
|
||||
if [[ -z $UI_TOOL ]]; then
|
||||
ask 'CTIDs auswaehlen (Leerzeichen, oder all; leer = abbrechen):'
|
||||
SELECTION=$REPLY
|
||||
[[ -n $SELECTION ]]
|
||||
return
|
||||
fi
|
||||
menu_height=$((UI_HEIGHT-9))
|
||||
if [[ $menu_height -gt ${#IDS[@]} ]]; then menu_height=${#IDS[@]}; fi
|
||||
for id in "${IDS[@]}"; do
|
||||
items+=("$id" "${NAMES[$id]} | Tailscale: $(installed_label "${TS[$id]}") | Wazuh: $(installed_label "${WZ[$id]}") | TUN: $(installed_label "${TUN[$id]}")" OFF)
|
||||
done
|
||||
# UI reads/writes the controlling terminal. Only CTIDs go to captured fd 4.
|
||||
# Never eval/source the dialog output; the normal selection validation follows.
|
||||
if ui_capture --title 'LXC Enrollment - Container auswaehlen' \
|
||||
--ok-button 'Weiter' --cancel-button 'Abbrechen' \
|
||||
--separate-output --checklist \
|
||||
'Pfeile: navigieren | Leertaste: markieren | Tab: Schaltflaeche | Enter: bestaetigen' \
|
||||
"$UI_HEIGHT" "$UI_WIDTH" "$menu_height" "${items[@]}"; then
|
||||
SELECTION=${REPLY//$'\n'/ }
|
||||
[[ -n $SELECTION ]]
|
||||
return
|
||||
else
|
||||
rc=$?
|
||||
case "$rc" in 1|255) return 1;; *) fail "LXC-Checkliste fehlgeschlagen (Status $rc).";; esac
|
||||
fi
|
||||
}
|
||||
|
||||
ensure_tun() {
|
||||
local id=$1 cfg slot=-1 n
|
||||
cfg=$(pct config "$id") || return 1
|
||||
@@ -359,16 +442,17 @@ deploy_one() {
|
||||
}
|
||||
|
||||
main() {
|
||||
local id input wanted found need_ts=0 need_wz=0 restart_ids='' ok='' failed='' auto_version password
|
||||
local id input wanted found need_ts=0 need_wz=0 restart_ids='' ok='' failed='' auto_version password plan=''
|
||||
scan
|
||||
[[ $LIST == 0 ]] || return 0
|
||||
[[ ${#IDS[@]} -gt 0 ]] || { say 'Keine passenden LXCs gefunden.'; return 0; }
|
||||
exec 3<>/dev/tty || fail 'Interaktives Terminal fehlt. --list kann ohne Terminal laufen.'
|
||||
init_ui
|
||||
load_settings
|
||||
yes_no "Tailscale SSH fuer alle ausgewaehlten LXCs aktivieren? $(choice_hint "$SSH_ENABLED")" "$SSH_ENABLED"
|
||||
SSH_ENABLED=$REPLY
|
||||
if [[ $SSH_ENABLED == 1 ]]; then
|
||||
ask "SSH-Nutzername${SSH_USER:+ [$SSH_USER]}:"
|
||||
ask "SSH-Nutzername${SSH_USER:+ [$SSH_USER]}:" "$SSH_USER"
|
||||
SSH_USER=${REPLY:-$SSH_USER}
|
||||
[[ $SSH_USER =~ ^[a-z_][a-z0-9_-]{0,30}$ && $SSH_USER != root ]] || fail 'Bitte einen normalen Linux-Nutzernamen verwenden.'
|
||||
yes_no "Nutzer zu sudo hinzufuegen? $(choice_hint "$SSH_SUDO")" "$SSH_SUDO"; SSH_SUDO=$REPLY
|
||||
@@ -377,7 +461,9 @@ main() {
|
||||
fi
|
||||
fi
|
||||
yes_no 'Einstellungen ohne Geheimnisse lokal in .vars speichern? [J/n]' 1; SAVE_SETTINGS=$REPLY
|
||||
if [[ -z $SELECTION ]]; then ask 'CTIDs auswaehlen (Leerzeichen, oder all; leer = abbrechen):'; SELECTION=$REPLY; fi
|
||||
if [[ -z $SELECTION ]]; then
|
||||
choose_lxcs || { say 'Abgebrochen; keine Container ausgewaehlt.'; return 0; }
|
||||
fi
|
||||
[[ -n $SELECTION ]] || return 0
|
||||
if [[ $SELECTION == all ]]; then SELECTED=("${IDS[@]}"); else
|
||||
SELECTION=${SELECTION//,/ }
|
||||
@@ -393,6 +479,7 @@ main() {
|
||||
say ''; say 'Geplante Aenderungen:'
|
||||
for id in "${SELECTED[@]}"; do
|
||||
say "LXC $id ${NAMES[$id]}: Tailscale $(installed_label "${TS[$id]}"), Wazuh $(installed_label "${WZ[$id]}")."
|
||||
plan+="LXC $id ${NAMES[$id]}: Tailscale $(installed_label "${TS[$id]}"), Wazuh $(installed_label "${WZ[$id]}")"$'\n'
|
||||
if [[ ${TS[$id]} == 0 || $RESUME_TS == 1 ]]; then
|
||||
need_ts=1
|
||||
if [[ ${TUN[$id]} == 0 ]]; then restart_ids+=" $id"; fi
|
||||
@@ -411,7 +498,7 @@ main() {
|
||||
exec 8>/run/lxc-enroll.lock
|
||||
flock -n 8 || fail 'Ein anderer Enrollment-Lauf ist bereits aktiv.'
|
||||
if [[ $need_wz == 1 ]]; then
|
||||
if [[ -z $MANAGER ]]; then ask 'Erreichbare Wazuh-Manager-Adresse (LAN-IP oder Headscale-IP):'; MANAGER=$REPLY; fi
|
||||
if [[ -z $MANAGER ]]; then ask 'Erreichbare Wazuh-Manager-Adresse (IP oder DNS-Name):'; MANAGER=$REPLY; fi
|
||||
[[ $MANAGER =~ ^[A-Za-z0-9][A-Za-z0-9.:-]*$ ]] || fail 'Manager-Adresse ungueltig.'
|
||||
if [[ ${#MANAGERS[@]} == 1 ]]; then
|
||||
auto_version=$(pct exec "${MANAGERS[0]}" -- dpkg-query -W '-f=${Version}' wazuh-manager) || fail 'Manager-Version nicht lesbar.'
|
||||
@@ -435,7 +522,19 @@ main() {
|
||||
else
|
||||
say 'Neue Clients behalten lokales DNS bei. Der Manager-Name muss ueber diesen Resolver aufloesbar sein.'
|
||||
fi
|
||||
ask 'Nur diese fehlenden Komponenten installieren? Bitte INSTALL eingeben:'
|
||||
if [[ -n $UI_TOOL ]]; then
|
||||
local -a scroll_option=()
|
||||
if [[ $UI_TOOL == whiptail ]]; then scroll_option=(--scrolltext); else scroll_option=(--scrollbar); fi
|
||||
plan+=$'\n'"Wazuh-Manager: ${MANAGER:-nicht benoetigt}; neue Agent-Version: ${VERSION:-keine}"$'\n'
|
||||
plan+="Headscale: ${LOGIN_SERVER:-nicht benoetigt}; DNS uebernehmen: $(yesno_label "$TS_ACCEPT_DNS")"$'\n'
|
||||
plan+="Tailscale SSH: $(yesno_label "$SSH_ENABLED"); Nutzer: ${SSH_USER:-keiner}; Sudo: $(yesno_label "$SSH_SUDO"); Sudo ohne Passwort: $(yesno_label "$SSH_NOPASSWD")"$'\n'
|
||||
if [[ $SSH_ENABLED == 1 ]]; then plan+='Tailscale-SSH-Sitzungen koennen unterbrochen werden. Zugriff braucht eine passende Headscale-Policy.'$'\n'; fi
|
||||
plan+="TUN ergaenzen und neu starten:${restart_ids:- keine}"$'\n'
|
||||
if [[ $RESUME_TS == 1 ]]; then plan+='Wiederaufnahme: noch nicht angemeldetes Tailscale anmelden.'$'\n'; fi
|
||||
ui_capture --title 'LXC Enrollment - Geplante Aenderungen' --ok-button 'Pruefen und weiter' \
|
||||
"${scroll_option[@]}" --msgbox "$plan" "$UI_HEIGHT" "$UI_WIDTH" || fail 'Pruefung abgebrochen.'
|
||||
fi
|
||||
ask 'Nur diese fehlenden Komponenten und gewaehlten Einstellungen einrichten? Bitte INSTALL eingeben:'
|
||||
[[ $REPLY == INSTALL ]] || { say 'Abgebrochen.'; return 0; }
|
||||
if [[ -n $restart_ids ]]; then
|
||||
ask "Diese Container werden kurz unterbrochen:$restart_ids. Bitte NEUSTART eingeben:"
|
||||
|
||||
Reference in New Issue
Block a user