Integrate Server Monitor installer and real E2E tests #17
1 changed files with 162 additions and 0 deletions
162
ochenstarik-server-monitor-manager.sh
Normal file
162
ochenstarik-server-monitor-manager.sh
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
readonly APP_NAME="ochenstarik-server-monitor-manager"
|
||||
readonly MONITOR_USER="ochenstarik-monitor"
|
||||
readonly MONITOR_HOME="/var/lib/${APP_NAME}"
|
||||
readonly MONITOR_COMMAND="/usr/local/libexec/ochenstarik-server-monitor"
|
||||
readonly AUTHORIZED_KEYS="${MONITOR_HOME}/.ssh/authorized_keys"
|
||||
|
||||
log() { printf '[+] %s\n' "$*"; }
|
||||
warn() { printf '[!] %s\n' "$*" >&2; }
|
||||
die() { printf '[x] %s\n' "$*" >&2; exit 1; }
|
||||
|
||||
require_root() {
|
||||
[[ "$EUID" -eq 0 ]] || die "Запустите скрипт через sudo"
|
||||
}
|
||||
|
||||
detect_system() {
|
||||
[[ -r /etc/os-release ]] || die "Не найден /etc/os-release"
|
||||
# shellcheck disable=SC1091
|
||||
. /etc/os-release
|
||||
case "${ID:-}" in
|
||||
ubuntu|debian) ;;
|
||||
*) die "Поддерживаются Ubuntu и Debian; обнаружено: ${ID:-unknown}" ;;
|
||||
esac
|
||||
command -v systemctl >/dev/null 2>&1 || die "Требуется systemd"
|
||||
}
|
||||
|
||||
read_public_key() {
|
||||
printf '\nВ Windows-приложении нажмите «SSH-ключ» → «Копировать».\n'
|
||||
read -rp 'Вставьте публичный ключ: ' PUBLIC_KEY
|
||||
PUBLIC_KEY="${PUBLIC_KEY//$'\r'/}"
|
||||
[[ "$PUBLIC_KEY" =~ ^ssh-ed25519[[:space:]]+[A-Za-z0-9+/]+={0,3}([[:space:]].*)?$ ]] \
|
||||
|| die "Ожидается публичный ключ формата ssh-ed25519 AAAA..."
|
||||
}
|
||||
|
||||
install_dependencies() {
|
||||
apt-get update
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
ca-certificates openssh-server openssh-client coreutils gawk
|
||||
systemctl enable --now ssh
|
||||
}
|
||||
|
||||
verify_public_key() {
|
||||
local key_file
|
||||
key_file="$(mktemp)"
|
||||
trap 'rm -f -- "${key_file:-}"' RETURN
|
||||
printf '%s\n' "$PUBLIC_KEY" > "$key_file"
|
||||
ssh-keygen -l -f "$key_file" >/dev/null \
|
||||
|| die "ssh-keygen отклонил публичный ключ"
|
||||
trap - RETURN
|
||||
rm -f -- "$key_file"
|
||||
}
|
||||
|
||||
create_monitor_command() {
|
||||
install -d -m 0755 -o root -g root "$(dirname "$MONITOR_COMMAND")"
|
||||
[[ ! -L "$MONITOR_COMMAND" ]] \
|
||||
|| die "Отказ от записи через символическую ссылку: $MONITOR_COMMAND"
|
||||
cat > "$MONITOR_COMMAND" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
export LC_ALL=C
|
||||
|
||||
read_mem_value() {
|
||||
awk -v key="$1" '$1 == key ":" { print $2; exit }' /proc/meminfo
|
||||
}
|
||||
|
||||
printf 'PROTOCOL=1\n'
|
||||
printf 'HOSTNAME=%s\n' "$(hostname)"
|
||||
printf 'UPTIME_SECONDS=%s\n' "$(cut -d. -f1 /proc/uptime)"
|
||||
printf 'LOAD1=%s\n' "$(cut -d' ' -f1 /proc/loadavg)"
|
||||
printf 'CPU_COUNT=%s\n' "$(getconf _NPROCESSORS_ONLN)"
|
||||
printf 'MEM_TOTAL_KB=%s\n' "$(read_mem_value MemTotal)"
|
||||
printf 'MEM_AVAILABLE_KB=%s\n' "$(read_mem_value MemAvailable)"
|
||||
df -Pk / | awk 'NR == 2 {
|
||||
printf "DISK_TOTAL_KB=%s\nDISK_AVAILABLE_KB=%s\n", $2, $4
|
||||
}'
|
||||
printf 'KERNEL=%s\n' "$(uname -r)"
|
||||
EOF
|
||||
chown root:root "$MONITOR_COMMAND"
|
||||
chmod 0755 "$MONITOR_COMMAND"
|
||||
}
|
||||
|
||||
create_monitor_user() {
|
||||
if ! getent passwd "$MONITOR_USER" >/dev/null; then
|
||||
useradd \
|
||||
--system \
|
||||
--create-home \
|
||||
--home-dir "$MONITOR_HOME" \
|
||||
--shell /bin/bash \
|
||||
"$MONITOR_USER"
|
||||
fi
|
||||
usermod --home "$MONITOR_HOME" --shell /bin/bash "$MONITOR_USER"
|
||||
passwd -l "$MONITOR_USER" >/dev/null 2>&1 || true
|
||||
|
||||
install -d -m 0750 -o "$MONITOR_USER" -g "$MONITOR_USER" "$MONITOR_HOME"
|
||||
install -d -m 0700 -o "$MONITOR_USER" -g "$MONITOR_USER" "${MONITOR_HOME}/.ssh"
|
||||
[[ ! -L "$AUTHORIZED_KEYS" ]] \
|
||||
|| die "Отказ от записи через символическую ссылку: $AUTHORIZED_KEYS"
|
||||
printf 'restrict,command="%s" %s\n' "$MONITOR_COMMAND" "$PUBLIC_KEY" > "$AUTHORIZED_KEYS"
|
||||
chown "$MONITOR_USER:$MONITOR_USER" "$AUTHORIZED_KEYS"
|
||||
chmod 0600 "$AUTHORIZED_KEYS"
|
||||
}
|
||||
|
||||
verify_sshd() {
|
||||
sshd -t
|
||||
sshd -T | grep -qi '^pubkeyauthentication yes$' \
|
||||
|| die "В sshd отключена аутентификация по публичному ключу"
|
||||
}
|
||||
|
||||
show_status() {
|
||||
local ssh_port="unknown"
|
||||
if command -v sshd >/dev/null 2>&1; then
|
||||
ssh_port="$(sshd -T 2>/dev/null | awk '$1 == "port" { print $2; exit }')"
|
||||
fi
|
||||
printf 'Пользователь: %s\n' "$MONITOR_USER"
|
||||
printf 'SSH-порт: %s\n' "${ssh_port:-unknown}"
|
||||
printf 'Команда: %s\n' "$MONITOR_COMMAND"
|
||||
if [[ -x "$MONITOR_COMMAND" ]]; then
|
||||
runuser -u "$MONITOR_USER" -- "$MONITOR_COMMAND"
|
||||
else
|
||||
warn "Серверная часть ещё не установлена"
|
||||
fi
|
||||
}
|
||||
|
||||
install_server_part() {
|
||||
read_public_key
|
||||
install_dependencies
|
||||
verify_public_key
|
||||
create_monitor_command
|
||||
create_monitor_user
|
||||
verify_sshd
|
||||
systemctl reload ssh
|
||||
log "Серверная часть установлена"
|
||||
log "Входящий порт не изменялся, новые правила UFW не создавались"
|
||||
show_status
|
||||
}
|
||||
|
||||
uninstall_server_part() {
|
||||
local answer
|
||||
read -rp 'Удалить пользователя мониторинга и forced-command? [y/N]: ' answer
|
||||
[[ "$answer" =~ ^[Yy]$ ]] || { log "Отменено"; return 0; }
|
||||
rm -f -- "$MONITOR_COMMAND"
|
||||
if getent passwd "$MONITOR_USER" >/dev/null; then
|
||||
userdel --remove "$MONITOR_USER" 2>/dev/null || userdel "$MONITOR_USER"
|
||||
fi
|
||||
log "Серверная часть удалена"
|
||||
}
|
||||
|
||||
main() {
|
||||
local action="${1:-install}"
|
||||
require_root
|
||||
detect_system
|
||||
case "$action" in
|
||||
install) install_server_part ;;
|
||||
status) show_status ;;
|
||||
uninstall) uninstall_server_part ;;
|
||||
*) die "Использование: $0 [install|status|uninstall]" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Loading…
Reference in a new issue