feat: initial commit

This commit is contained in:
redtea committed 2026-10-13 00:25:29 +03:00
1 parent 353f62e257
commit c6852c6f1b
62 files changed
+5911 -2

No files matched your search

+165
View File
@@ -0,0 +1,165 @@
#!/bin/sh
# LPRA agent installer.
# Usage (non-interactive):
# curl -fsSL {{.Host}}/install.sh | sudo HOST={{.Host}} ENROLL_SECRET=xxxx sh
# Usage (interactive, will ask for the secret):
# curl -fsSL {{.Host}}/install.sh | sudo sh
set -eu
HOST="${HOST:-{{.Host}}}"
{{if .Secret}}ENROLL_SECRET="${ENROLL_SECRET:-{{.Secret}}}"
{{end}}
BIN_PATH="/usr/local/bin/lpagent"
CONF_DIR="/etc/lpagent"
CONF_FILE="$CONF_DIR/config.env"
STATE_FILE="$CONF_DIR/state.json"
SERVICE="/etc/systemd/system/lpagent.service"
red() { printf '\033[31m%s\033[0m\n' "$1"; }
green() { printf '\033[32m%s\033[0m\n' "$1"; }
bold() { printf '\033[1m%s\033[0m\n' "$1"; }
# Read a line from the real terminal even when the script is piped into `sh`.
ask() { # ask VARNAME "prompt"
_v=""
if [ -r /dev/tty ]; then
printf '%s' "$2" > /dev/tty
read -r _v < /dev/tty || true
fi
eval "$1=\$_v"
}
confirm() { # confirm "prompt" -> returns 0 on yes
if [ ! -r /dev/tty ]; then return 1; fi
printf '%s [y/N]: ' "$1" > /dev/tty
read -r _a < /dev/tty || _a=""
case "$_a" in y|Y|yes|YES) return 0 ;; *) return 1 ;; esac
}
# --- root check -------------------------------------------------------------
if [ "$(id -u)" -ne 0 ]; then
red "Нужны права root."
echo "Запустите через sudo, например:"
echo " curl -fsSL $HOST/install.sh | sudo sh"
exit 1
fi
# --- systemd check ----------------------------------------------------------
if ! command -v systemctl >/dev/null 2>&1; then
red "systemctl не найден: поддерживаются только системы с systemd."
exit 1
fi
uninstall() {
bold "Удаление агента LPRA…"
systemctl stop lpagent 2>/dev/null || true
systemctl disable lpagent 2>/dev/null || true
rm -f "$SERVICE"
systemctl daemon-reload 2>/dev/null || true
rm -f "$BIN_PATH"
rm -rf "$CONF_DIR"
green "Агент удалён."
}
# --- existing installation --------------------------------------------------
if [ -f "$SERVICE" ] || [ -f "$BIN_PATH" ]; then
bold "Агент LPRA уже установлен на этой машине."
if confirm "Удалить его сейчас?"; then
uninstall
if confirm "Установить заново?"; then
: # fall through to install
else
exit 0
fi
else
if confirm "Переустановить / обновить?"; then
: # fall through, keep existing state.json (не будет повторной регистрации)
else
echo "Ничего не делаю."
exit 0
fi
fi
fi
# --- architecture -----------------------------------------------------------
case "$(uname -m)" in
x86_64|amd64) ARCH=amd64 ;;
aarch64|arm64) ARCH=arm64 ;;
*) red "Неподдерживаемая архитектура: $(uname -m)"; exit 1 ;;
esac
# --- machine name -----------------------------------------------------------
# Default: <hostname>-<4 random chars>. Only used at the first enrollment.
if [ -z "${AGENT_NAME:-}" ]; then
SUFFIX="$(head -c16 /dev/urandom 2>/dev/null | od -An -tx1 2>/dev/null | tr -d ' \n' | cut -c1-4)"
[ -z "$SUFFIX" ] && SUFFIX="$(date +%s | tail -c 5)"
AGENT_NAME="$(hostname 2>/dev/null || echo host)-$SUFFIX"
fi
# --- enroll secret ----------------------------------------------------------
# Needed only for the very first enrollment; skipped if state.json already exists.
if [ -z "${ENROLL_SECRET:-}" ] && [ ! -f "$STATE_FILE" ]; then
ask ENROLL_SECRET "Введите enroll-секрет (из панели, раздел Настройки): "
if [ -z "${ENROLL_SECRET:-}" ]; then
red "Enroll-секрет обязателен для первой установки."
exit 1
fi
fi
# --- downloader -------------------------------------------------------------
download() { # download URL DEST
if command -v curl >/dev/null 2>&1; then
curl -fSL -o "$2" "$1"
elif command -v wget >/dev/null 2>&1; then
wget -qO "$2" "$1"
else
red "Нужен curl или wget."; exit 1
fi
}
bold "Скачивание агента ($ARCH) с $HOST…"
TMP="$(mktemp)"
download "$HOST/download/agent-linux-$ARCH" "$TMP"
install -m 0755 "$TMP" "$BIN_PATH"
rm -f "$TMP"
green "Бинарник установлен: $BIN_PATH"
# --- config -----------------------------------------------------------------
mkdir -p "$CONF_DIR"
chmod 700 "$CONF_DIR"
umask 077
cat > "$CONF_FILE" <<EOF
HOST=$HOST
ENROLL_SECRET=${ENROLL_SECRET:-}
AGENT_NAME=$AGENT_NAME
STATE_PATH=$STATE_FILE
EOF
chmod 600 "$CONF_FILE"
# --- systemd unit -----------------------------------------------------------
cat > "$SERVICE" <<EOF
[Unit]
Description=LPRA remote access agent
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
EnvironmentFile=$CONF_FILE
ExecStart=$BIN_PATH
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable lpagent >/dev/null 2>&1 || true
systemctl restart lpagent
sleep 1
bold "Статус сервиса:"
systemctl --no-pager --full status lpagent || true
echo
green "Готово. Машина должна появиться в панели: $HOST"