#!/bin/bash # archivmail Server-Installer # Unterstützte Systeme: Debian 12 / 13 # Aufruf: bash install.sh # Mit eigenem DB-Passwort: DB_PASSWORD=geheim bash install.sh set -euo pipefail RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m' log() { echo -e "${GREEN}[OK]${NC} $*"; } info() { echo -e "${BLUE}[..]${NC} $*"; } warn() { echo -e "${YELLOW}[!!]${NC} $*"; } die() { echo -e "${RED}[ERR]${NC} $*" >&2; exit 1; } [[ $EUID -eq 0 ]] || die "Bitte als root ausführen: sudo bash install.sh" DB_PASSWORD="${DB_PASSWORD:-$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 32)}" API_SECRET="${API_SECRET:-$(openssl rand -base64 48 | tr -dc 'a-zA-Z0-9' | head -c 64)}" INSTALL_DIR="/opt/archivmail" STORE_DIR="/var/archivmail" LOG_DIR="/var/log/archivmail" CONFIG_DIR="/etc/archivmail" AM_USER="archivmail" echo "" echo " ╔══════════════════════════════════════╗" echo " ║ archivmail Installer v1.0 ║" echo " ╚══════════════════════════════════════╝" echo "" # ── 1. Pakete ───────────────────────────────────────────────────────────────── info "Installiere Systempakete..." apt-get update -qq apt-get install -y -qq \ golang-go nodejs npm postgresql nginx \ libxapian-dev pkg-config build-essential \ curl git logrotate openssl log "Pakete installiert" # ── 2. Systembenutzer ───────────────────────────────────────────────────────── info "Lege Systembenutzer '$AM_USER' an..." id "$AM_USER" &>/dev/null \ && log "Benutzer '$AM_USER' existiert bereits" \ || { useradd --system --shell /bin/false --home "$STORE_DIR" --create-home "$AM_USER"; log "Benutzer angelegt"; } # ── 3. Verzeichnisstruktur ──────────────────────────────────────────────────── info "Erstelle Verzeichnisstruktur..." mkdir -p "$STORE_DIR/store" "$STORE_DIR/astore" "$STORE_DIR/xapian" mkdir -p "$CONFIG_DIR" "$LOG_DIR" "$INSTALL_DIR" "$INSTALL_DIR/web" chown -R "$AM_USER:$AM_USER" "$STORE_DIR" "$LOG_DIR" chmod 755 "$STORE_DIR" chmod 700 "$STORE_DIR/store" "$STORE_DIR/astore" "$STORE_DIR/xapian" log "Verzeichnisse erstellt" # ── 4. Keyfile ──────────────────────────────────────────────────────────────── info "Generiere Verschlüsselungs-Keyfile..." if [ ! -f "$CONFIG_DIR/keyfile" ]; then openssl rand -base64 32 > "$CONFIG_DIR/keyfile" chmod 400 "$CONFIG_DIR/keyfile" chown "$AM_USER:$AM_USER" "$CONFIG_DIR/keyfile" log "Keyfile generiert: $CONFIG_DIR/keyfile" else log "Keyfile existiert bereits – wird nicht überschrieben" fi # ── 5. PostgreSQL ───────────────────────────────────────────────────────────── info "Richte PostgreSQL ein..." systemctl enable postgresql --quiet systemctl start postgresql su -c "psql -tc \"SELECT 1 FROM pg_roles WHERE rolname='archivmail'\" | grep -q 1 \ && psql -c \"ALTER USER archivmail WITH PASSWORD '$DB_PASSWORD'\" \ || psql -c \"CREATE USER archivmail WITH PASSWORD '$DB_PASSWORD'\"" postgres su -c "psql -tc \"SELECT 1 FROM pg_database WHERE datname='archivmail'\" | grep -q 1 || \ psql -c \"CREATE DATABASE archivmail OWNER archivmail\"" postgres su -c "psql archivmail -c \"GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO archivmail;\"" postgres su -c "psql archivmail -c \"GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO archivmail;\"" postgres su -c "psql archivmail -c \"ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO archivmail;\"" postgres su -c "psql archivmail -c \"ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO archivmail;\"" postgres log "PostgreSQL-Schema angelegt" log "Standard-Benutzer werden beim ersten Daemon-Start angelegt" # ── 6. Konfiguration ────────────────────────────────────────────────────────── info "Erstelle Konfigurationsdatei..." cat > "$CONFIG_DIR/config.yml" << CONFIG # archivmail Konfiguration – generiert am $(date -u +%Y-%m-%dT%H:%M:%SZ) server: api_port: 8080 smtp_port: 2525 database: host: 127.0.0.1 port: 5432 name: archivmail user: archivmail password: ${DB_PASSWORD} sslmode: disable storage: store_path: ${STORE_DIR}/store astore_path: ${STORE_DIR}/astore xapian_path: ${STORE_DIR}/xapian keyfile: ${CONFIG_DIR}/keyfile api: bind: ":8080" secret: ${API_SECRET} index: path: ${STORE_DIR}/xapian backend: xapian batch_size: 100 audit: log_path: ${LOG_DIR}/audit.log retention_days: 0 smtp: bind: ":2525" allowed_ips: - 127.0.0.1 CONFIG chmod 640 "$CONFIG_DIR/config.yml" chown "root:$AM_USER" "$CONFIG_DIR/config.yml" log "Konfiguration: $CONFIG_DIR/config.yml" # ── 7. Nginx ────────────────────────────────────────────────────────────────── info "Konfiguriere Nginx..." cat > /etc/nginx/sites-available/archivmail << 'NGINX' server { listen 80; server_name _; location / { proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_cache_bypass $http_upgrade; } location /api/ { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 512M; } access_log /var/log/nginx/archivmail.access.log; error_log /var/log/nginx/archivmail.error.log; } NGINX ln -sf /etc/nginx/sites-available/archivmail /etc/nginx/sites-enabled/archivmail rm -f /etc/nginx/sites-enabled/default nginx -t systemctl enable nginx --quiet systemctl restart nginx log "Nginx konfiguriert" # ── 8. logrotate ────────────────────────────────────────────────────────────── cat > /etc/logrotate.d/archivmail << LOGROTATE ${LOG_DIR}/audit.log { daily rotate 365 compress delaycompress missingok notifempty create 640 ${AM_USER} ${AM_USER} } LOGROTATE log "logrotate konfiguriert" # ── 9. systemd Units ────────────────────────────────────────────────────────── info "Erstelle systemd Units..." cat > /etc/systemd/system/archivmail.service << UNIT [Unit] Description=archivmail Mail Archive Daemon After=network.target postgresql.service Requires=postgresql.service [Service] Type=simple User=${AM_USER} Group=${AM_USER} ExecStart=${INSTALL_DIR}/archivmail --config ${CONFIG_DIR}/config.yml Restart=on-failure RestartSec=5 StandardOutput=journal StandardError=journal SyslogIdentifier=archivmail NoNewPrivileges=true ProtectSystem=strict ReadWritePaths=${STORE_DIR} ${LOG_DIR} ReadOnlyPaths=${CONFIG_DIR} [Install] WantedBy=multi-user.target UNIT cat > /etc/systemd/system/archivmail-web.service << UNIT [Unit] Description=archivmail Web Frontend After=network.target archivmail.service [Service] Type=simple User=${AM_USER} Group=${AM_USER} WorkingDirectory=${INSTALL_DIR}/web ExecStart=/usr/bin/node server.js Environment=NODE_ENV=production Environment=PORT=3000 Environment=NEXT_PUBLIC_API_URL=http://127.0.0.1:8080 Restart=on-failure RestartSec=5 StandardOutput=journal StandardError=journal SyslogIdentifier=archivmail-web [Install] WantedBy=multi-user.target UNIT systemctl daemon-reload log "systemd Units erstellt" # ── Abschlussbericht ────────────────────────────────────────────────────────── echo "" echo " ╔══════════════════════════════════════════════════════════╗" echo " ║ Installation abgeschlossen! ║" echo " ╚══════════════════════════════════════════════════════════╝" echo "" echo " Pfade:" echo " Binaries: $INSTALL_DIR/" echo " Mail-Speicher: $STORE_DIR/" echo " Konfiguration: $CONFIG_DIR/config.yml" echo " Keyfile: $CONFIG_DIR/keyfile (chmod 400 – sicher aufbewahren!)" echo " Logs: $LOG_DIR/" echo "" echo " Datenbank:" echo " Host: 127.0.0.1:5432 / archivmail" printf " Passwort: %s\n" "$DB_PASSWORD" echo "" echo " Standard-Zugangsdaten (nach Deployment ändern!):" echo " Admin: admin@archivmail / archivmailrockz" echo " Auditor: auditor@archivmail / archivmailrockz" echo "" echo " Nächste Schritte nach Deployment:" echo " 1. cp archivmail $INSTALL_DIR/" echo " 2. cp -r web/ $INSTALL_DIR/web/" echo " 3. systemctl enable --now archivmail archivmail-web" echo "" warn "DB-Passwort steht in $CONFIG_DIR/config.yml (chmod 640, root:archivmail)" warn "Standardpasswörter unbedingt nach dem ersten Login ändern!" echo ""