#!/bin/bash # ══════════════════════════════════════════════════════════════════════════════ # NetCell MailGuard — One-Liner Installer # # curl -fsSL https://get.netcell-mailguard.de | sudo bash # # Supported: Debian 12/13, Ubuntu 24.04 (amd64 + arm64) # ══════════════════════════════════════════════════════════════════════════════ set -euo pipefail # ─── 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}NetCell MailGuard${NC} — Installer" echo -e " ${DIM}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo "" # ─── Root check ─────────────────────────────────────────────────────────────── [ "$(id -u)" -ne 0 ] && fail "Please run as root: curl -fsSL https://get.netcell-mailguard.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" =~ ^(12|13)$ ]] || fail "Debian $OS_VERSION not supported (only 12/13)." ;; ubuntu) [[ "$OS_VERSION" == "24.04" ]] || fail "Ubuntu $OS_VERSION not supported (only 24.04)." ;; *) fail "$OS_ID not supported (only Debian 12/13, Ubuntu 24.04)." ;; 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}" # ─── 1. Update system ──────────────────────────────────────────────────────── 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 repository ──────────────────────────────────────────────────── # Dedizierter Keyring + sources.list pro Produkt. Inhalt ist identisch zu # enconf, aber die Dateien sind getrennt, damit eine eventuelle Deinstallation # von MailGuard den enconf-Source nicht antastet. setup_repo() { mkdir -p /etc/apt/keyrings curl -fsSL "https://git.netcell-it.de/api/packages/projekte/debian/repository.key" \ -o /etc/apt/keyrings/nmg.asc echo "deb [signed-by=/etc/apt/keyrings/nmg.asc] https://git.netcell-it.de/api/packages/projekte/debian bookworm main" \ > /etc/apt/sources.list.d/nmg.list apt-get update -qq } step "Set up NetCell MailGuard apt repository" setup_repo AVAILABLE=$(apt-cache policy nmg 2>/dev/null | grep Candidate | awk '{print $2}') if [ -n "$AVAILABLE" ] && [ "$AVAILABLE" != "(none)" ]; then step_log "Version ${BLD}${AVAILABLE}${NC} available" fi # ─── 3. Install NetCell MailGuard ──────────────────────────────────────────── install_nmg() { local apt_opts=(-y -qq -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef) if ! DEBIAN_FRONTEND=noninteractive apt-get install "${apt_opts[@]}" nmg; 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[@]}" nmg fi } step "Install NetCell MailGuard" install_nmg # ─── 4. Services prüfen ────────────────────────────────────────────────────── # Prüfe nur die Units, die der nmg-Postinst tatsächlich enabled — plus # die externen Dienste, auf denen wir aufbauen. for svc in nmg-api nmg-scheduler nmg-sandbox nmg-archive postfix rspamd nginx; do if systemctl list-unit-files --no-legend "${svc}.service" >/dev/null 2>&1 && \ systemctl cat "${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 # ─── Result ────────────────────────────────────────────────────────────────── SERVER_IP=$(hostname -I 2>/dev/null | awk '{print $1}') FQDN=$(hostname -f 2>/dev/null || hostname) URL_HOST="${FQDN:-$SERVER_IP}" echo "" echo -e " ${DIM}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo "" echo -e " ${GRN}${BLD}Installation complete!${NC}" echo "" echo -e " ${BLD}▸ Setup wizard:${NC} ${CYN}https://${URL_HOST}/setup${NC}" echo "" echo -e " ${DIM}Open the URL in your browser to configure MailGuard.${NC}" echo -e " ${DIM}(SSL certificate is self-signed on first boot — confirm the browser warning,${NC}" echo -e " ${DIM} Let's Encrypt is issued after the MX hostname is set.)${NC}" echo ""