Files
edgeguard-native/scripts/install.sh
Debian 4f6b7b34fc feat: install.sh One-Liner-Bootstrap + System-Adressen-Card auf IP-Page
scripts/install.sh: full curl-Onliner für Debian 13 trixie analog
mail-gateway/scripts/install.sh — OS+Arch-Detection, Pre-flight-
Tools, GPG-Key (nmg.asc, geteilt mit mail-gateway), APT-Source-Line
trixie main, apt install edgeguard, Service-Smoke + healthz-Probe.
Bestimmungsort: get.netcell-edgeguard.de (Hosting separat).

UI: IP-Adressen-Page bekommt eine "Adressen am Kernel"-Card oben,
analog zur Networks-Page. Listet jede vom Kernel sichtbare IP
(lo + eth0 + …) mit Family-Tag (IPv4/IPv6) — read-only. Verwaltete
Adressen darunter wie zuvor. User-Feedback: "die bestehenden
IP-Adressen werden nicht angezeigt" — adressiert.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 16:23:58 +02:00

192 lines
8.7 KiB
Bash
Executable File

#!/bin/bash
# ══════════════════════════════════════════════════════════════════════════════
# EdgeGuard — One-Liner Installer
#
# curl -fsSL https://get.netcell-edgeguard.de | sudo bash
#
# Supported: Debian 13 (Trixie), amd64 + arm64.
# ══════════════════════════════════════════════════════════════════════════════
set -euo pipefail
# Locale auf C — sonst druckt apt/dpkg auf de_DE-Boxen lokalisierte
# Strings (z.B. "Installationskandidat:" statt "Candidate:") und unsere
# awk/grep-Parser matchen nicht.
export LC_ALL=C
export LANG=C
# ─── Colors + helpers ─────────────────────────────────────────────────────────
GRN="\033[0;32m"; RED="\033[0;31m"; YLW="\033[0;33m"; CYN="\033[0;36m"
BLD="\033[1m"; DIM="\033[2m"; NC="\033[0m"
CHECK="${GRN}${NC}"
CROSS="${RED}${NC}"
step() {
local label="$1"; shift
local spin_chars='⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏'
local pid
"$@" >/dev/null 2>&1 &
pid=$!
local i=0
local start=$SECONDS
while kill -0 "$pid" 2>/dev/null; do
local c="${spin_chars:i%${#spin_chars}:1}"
local elapsed=$(( SECONDS - start ))
printf "\r ${CYN}${c}${NC} ${label}... ${DIM}${elapsed}s${NC} "
sleep 0.1
i=$((i + 1))
done
local total=$(( SECONDS - start ))
if wait "$pid"; then
printf "\r ${CHECK} ${label} ${DIM}(${total}s)${NC} \n"
return 0
else
printf "\r ${CROSS} ${label} ${DIM}(${total}s)${NC} \n"
return 1
fi
}
step_log() { printf " ${CHECK} $1\n"; }
fail() { echo -e "\n ${CROSS} ${RED}$*${NC}\n"; exit 1; }
# ─── Banner ───────────────────────────────────────────────────────────────────
clear 2>/dev/null || true
echo ""
echo -e " ${CYN}${BLD}EdgeGuard${NC} — Installer"
echo -e " ${DIM}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
# ─── Root check ───────────────────────────────────────────────────────────────
[ "$(id -u)" -ne 0 ] && fail "Please run as root: curl -fsSL https://get.netcell-edgeguard.de | sudo bash"
# ─── OS / Arch check ──────────────────────────────────────────────────────────
if [ -f /etc/os-release ]; then
. /etc/os-release
OS_ID="$ID"
OS_VERSION="$VERSION_ID"
OS_CODENAME="${VERSION_CODENAME:-}"
else
fail "Operating system not detected."
fi
case "$OS_ID" in
debian) [[ "$OS_VERSION" == "13" ]] || fail "Debian $OS_VERSION not supported (only 13 Trixie)." ;;
*) fail "$OS_ID not supported (only Debian 13 Trixie)." ;;
esac
ARCH=$(dpkg --print-architecture 2>/dev/null || uname -m)
case "$ARCH" in
amd64|x86_64) ARCH="amd64" ;;
arm64|aarch64) ARCH="arm64" ;;
*) fail "Architecture $ARCH not supported (only amd64/arm64)." ;;
esac
step_log "${OS_ID^} ${OS_VERSION} (${OS_CODENAME}) · ${ARCH}"
# ─── Pre-flight: required tools ──────────────────────────────────────────────
for tool in curl apt-get gpg dpkg; do
command -v "$tool" >/dev/null 2>&1 || \
fail "$tool not found — install with: apt-get install -y curl gpg ca-certificates"
done
# ─── 1. Update system + prerequisites ────────────────────────────────────────
step "Update system" apt-get update -qq
step "Install prerequisites" bash -c "DEBIAN_FRONTEND=noninteractive apt-get install -y -qq -o Dpkg::Options::=--force-confold curl gnupg ca-certificates apt-transport-https"
# ─── 2. Set up EdgeGuard apt repository ──────────────────────────────────────
# Shared keyring with mail-gateway (User-Konvention: ein netcell-IT-
# Schlüssel für alle Produkte). Key direkt aus der Gitea-Package-Registry,
# kein eigener edgeguard.asc.
setup_repo() {
# Strip stale repo files left over from earlier installer attempts.
for stale_list in netcell-edgeguard.list edgeguard-old.list; do
[ -f "/etc/apt/sources.list.d/$stale_list" ] && rm -f "/etc/apt/sources.list.d/$stale_list"
done
mkdir -p /etc/apt/keyrings
if [ ! -f /etc/apt/keyrings/nmg.asc ]; then
curl -fsSL "https://git.netcell-it.de/api/packages/projekte/debian/repository.key" \
-o /etc/apt/keyrings/nmg.asc
fi
echo "deb [signed-by=/etc/apt/keyrings/nmg.asc] https://git.netcell-it.de/api/packages/projekte/debian trixie main" \
> /etc/apt/sources.list.d/edgeguard.list
apt-get update -qq
}
step "Set up EdgeGuard apt repository" setup_repo
AVAILABLE=$(LC_ALL=C apt-cache policy edgeguard 2>/dev/null | awk '/Candidate:/ {print $2; exit}' || true)
if [ -n "$AVAILABLE" ] && [ "$AVAILABLE" != "(none)" ]; then
step_log "Version ${BLD}${AVAILABLE}${NC} available"
else
fail "edgeguard package not visible in repository — check /etc/apt/sources.list.d/edgeguard.list"
fi
# ─── 3. Install EdgeGuard ────────────────────────────────────────────────────
install_edgeguard() {
local apt_opts=(-y -qq -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef)
if ! DEBIAN_FRONTEND=noninteractive apt-get install "${apt_opts[@]}" edgeguard; then
# Safety net: if a dependency's postinst half-configured, try
# to resolve before failing the whole installer.
DEBIAN_FRONTEND=noninteractive dpkg --configure -a >/dev/null 2>&1 || true
DEBIAN_FRONTEND=noninteractive apt-get install "${apt_opts[@]}" --fix-broken >/dev/null 2>&1 || true
DEBIAN_FRONTEND=noninteractive apt-get install "${apt_opts[@]}" edgeguard
fi
}
step "Install EdgeGuard" install_edgeguard
# ─── 4. Service smoke ────────────────────────────────────────────────────────
for svc in edgeguard-api edgeguard-scheduler haproxy postgresql; do
if systemctl list-unit-files --no-legend "${svc}.service" >/dev/null 2>&1; then
if systemctl is-active --quiet "$svc" 2>/dev/null; then
step_log "${svc} running"
else
printf " ${CROSS} ${svc} not active\n"
fi
fi
done
# Probe the API loopback — should answer /healthz within a couple of
# seconds. We retry briefly because postgresql.service can be slow on
# first boot.
api_ok=""
for _ in 1 2 3 4 5; do
if curl -fsS http://127.0.0.1:9443/healthz >/dev/null 2>&1; then
api_ok=1
break
fi
sleep 1
done
if [ -n "$api_ok" ]; then
step_log "edgeguard-api answering on 127.0.0.1:9443"
else
printf " ${YLW}!${NC} edgeguard-api not yet answering on :9443 — check 'systemctl status edgeguard-api'\n"
fi
# ─── Result ──────────────────────────────────────────────────────────────────
SERVER_IP=$(hostname -I 2>/dev/null | awk '{print $1}')
FQDN=$(hostname -f 2>/dev/null || hostname)
case "$FQDN" in *.*) ;; *) FQDN="" ;; esac # drop single-label hostnames
print_url() {
local label="$1" path="$2"
echo -e " ${BLD}${label}:${NC}"
[ -n "$SERVER_IP" ] && echo -e " ${CYN}https://${SERVER_IP}${path}${NC}"
[ -n "$FQDN" ] && echo -e " ${CYN}https://${FQDN}${path}${NC}"
}
echo ""
echo -e " ${DIM}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
echo -e " ${GRN}${BLD}Installation complete!${NC}"
echo ""
print_url "Setup wizard" "/setup"
echo ""
echo -e " ${DIM}Open the URL in your browser to configure EdgeGuard.${NC}"
echo -e " ${DIM}(SSL is self-signed on first boot — confirm the browser warning;${NC}"
echo -e " ${DIM} a real Let's Encrypt cert is issued after the FQDN is set.)${NC}"
echo ""