@@ -1,8 +1,11 @@
#!/bin/bash
# archivmail Server- Installer
# archivmail Installer
# Unterstützte Systeme: Debian 12 / 13
# Aufruf: bash install.sh
# Mit eigenem DB-Passwort: DB_PASSWORD=geheim bash install.sh
#
# Aufruf:
# bash install.sh # Interaktiv (Modus-Auswahl)
# INSTALL_MODE=native bash install.sh # Nativ (systemd, direkter Build)
# INSTALL_MODE=docker bash install.sh # Docker (alle Abhängigkeiten im Container)
set -euo pipefail
export DEBIAN_FRONTEND = noninteractive
@@ -15,8 +18,11 @@ die() { echo -e "${RED}[ERR]${NC} $*" >&2; exit 1; }
[ [ $EUID -eq 0 ] ] || die "Bitte als root ausführen: sudo bash install.sh"
# ── Gemeinsame Variablen ──────────────────────────────────────────────────────
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) } "
WEBHOOK_SECRET = " ${ WEBHOOK_SECRET :- $( openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | head -c 40) } "
INSTALL_DIR = "/opt/archivmail"
STORE_DIR = "/var/archivmail"
LOG_DIR = "/var/log/archivmail"
@@ -24,17 +30,358 @@ CONFIG_DIR="/etc/archivmail"
SSL_DIR = "/etc/ssl/archivmail"
AM_USER = "archivmail"
FQDN = " $( hostname -f 2>/dev/null || hostname) "
REPO_URL = " ${ REPO_URL :- https : //gitea.perlbach24.de/scripte /archivmail.git } "
REPO_URL = " ${ REPO_URL :- https : //github.com/yourorg /archivmail.git } "
# ── Banner ────────────────────────────────────────────────────────────────────
echo ""
echo " ╔══════════════════════════════════════╗"
echo " ║ archivmail Installer v1.1 ║"
echo " ╚══════════════════════════════════════╝"
echo " ╔══════════════════════════════════════════ ╗"
echo " ║ archivmail Installer v2.0 ║"
echo " ╚══════════════════════════════════════════ ╝"
echo ""
info " Hostname: $FQDN "
echo ""
# ── 1. Pakete ──── ─────────────────────────────────────────────────────────────
# ── Modus-Auswahl ─────────────────────────────────────────────────────────────
INSTALL_MODE = " ${ INSTALL_MODE :- } "
if [ [ -z " $INSTALL_MODE " ] ] ; then
echo " Installations-Modus wählen:"
echo ""
echo " 1) Nativ — Go/Node.js direkt auf dem Server kompiliert und gebaut"
echo " (systemd-Dienste, PostgreSQL lokal, kein Docker nötig)"
echo ""
echo " 2) Docker — Alle Abhängigkeiten (Go, Xapian, Node.js, PostgreSQL)"
echo " laufen in Containern. Kein Build-Toolchain auf dem Host."
echo " Deployment via GitHub Webhook (git pull → docker compose up)"
echo ""
read -rp " Auswahl [1/2]: " _choice
case " $_choice " in
1) INSTALL_MODE = "native" ; ;
2) INSTALL_MODE = "docker" ; ;
*) die " Ungültige Auswahl: $_choice " ; ;
esac
fi
[ [ " $INSTALL_MODE " = = "native" || " $INSTALL_MODE " = = "docker" ] ] \
|| die " INSTALL_MODE muss 'native' oder 'docker' sein (aktuell: $INSTALL_MODE ) "
echo ""
info " Modus: $INSTALL_MODE "
echo ""
# ══════════════════════════════════════════════════════════════════════════════
# DOCKER-INSTALLATION
# ══════════════════════════════════════════════════════════════════════════════
install_docker( ) {
# GitHub-Repo abfragen wenn nicht gesetzt
if [ [ " $REPO_URL " = = *"yourorg" * ] ] ; then
read -rp " GitHub-Repository URL (z.B. https://github.com/org/archivmail.git): " REPO_URL
[ [ -n " $REPO_URL " ] ] || die "Kein Repository angegeben."
fi
# ── Docker installieren ───────────────────────────────────────────────────
info "Installiere Docker..."
if command -v docker & >/dev/null; then
log " Docker bereits installiert: $( docker --version) "
else
apt-get update -qq
apt-get install -y -qq ca-certificates curl gnupg
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg \
| gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
echo " deb [arch= $( dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/debian $( . /etc/os-release && echo " $VERSION_CODENAME " ) stable " \
> /etc/apt/sources.list.d/docker.list
apt-get update -qq
apt-get install -y -qq docker-ce docker-ce-cli containerd.io docker-compose-plugin
systemctl enable --now docker
log " Docker $( docker --version) installiert "
fi
# ── Hilfspakete ───────────────────────────────────────────────────────────
info "Installiere Hilfspakete..."
apt-get install -y -qq git curl nginx openssl logrotate
log "Pakete installiert"
# ── webhook-Binary (adnanh/webhook) ──────────────────────────────────────
info "Installiere webhook-Empfänger..."
if ! command -v webhook & >/dev/null; then
WEBHOOK_BIN_VERSION = "2.8.2"
_arch = " $( dpkg --print-architecture) "
[ [ " $_arch " = = "amd64" ] ] && _arch = "linux_amd64"
[ [ " $_arch " = = "arm64" ] ] && _arch = "linux_arm64"
curl -fsSL \
" https://github.com/adnanh/webhook/releases/download/ ${ WEBHOOK_BIN_VERSION } /webhook- ${ _arch } .tar.gz " \
| tar -xz -C /usr/local/bin --strip-components= 1 " webhook- ${ _arch } /webhook "
chmod +x /usr/local/bin/webhook
log " webhook ${ WEBHOOK_BIN_VERSION } installiert "
else
log "webhook bereits installiert"
fi
# ── Verzeichnisse ─────────────────────────────────────────────────────────
info "Erstelle Verzeichnisse..."
mkdir -p " $CONFIG_DIR " " $LOG_DIR "
log "Verzeichnisse erstellt"
# ── Repository klonen ─────────────────────────────────────────────────────
info "Klone Repository..."
if [ [ -d " $INSTALL_DIR /.git " ] ] ; then
log "Repository existiert bereits — git pull"
git -C " $INSTALL_DIR " pull origin main
else
git clone " $REPO_URL " " $INSTALL_DIR "
log " Repository geklont: $INSTALL_DIR "
fi
# ── Keyfile ───────────────────────────────────────────────────────────────
info "Generiere Verschlüsselungs-Keyfile..."
if [ [ ! -f " $CONFIG_DIR /keyfile " ] ] ; then
openssl rand -base64 32 > " $CONFIG_DIR /keyfile "
chmod 400 " $CONFIG_DIR /keyfile "
log " Keyfile generiert: $CONFIG_DIR /keyfile "
else
log "Keyfile existiert bereits – wird nicht überschrieben"
fi
# ── TLS-Zertifikat ────────────────────────────────────────────────────────
info "Erstelle selbstsigniertes TLS-Zertifikat..."
mkdir -p " $SSL_DIR "
if [ [ ! -f " $SSL_DIR /archivmail.crt " ] ] ; then
SERVER_IP = " $( hostname -I | awk '{print $1}' ) "
openssl req -x509 -nodes -days 3650 -newkey rsa:4096 \
-keyout " $SSL_DIR /archivmail.key " \
-out " $SSL_DIR /archivmail.crt " \
-subj " /CN= ${ FQDN } /O=archivmail/C=DE " \
-addext " subjectAltName=DNS: ${ FQDN } ,DNS: $( hostname -s) ,IP: ${ SERVER_IP } " \
2>/dev/null
chmod 640 " $SSL_DIR /archivmail.key "
chmod 644 " $SSL_DIR /archivmail.crt "
log "TLS-Zertifikat erstellt"
else
log "TLS-Zertifikat existiert bereits – wird nicht überschrieben"
fi
# ── config.yml aus Vorlage ────────────────────────────────────────────────
info "Erstelle Konfigurationsdatei..."
if [ [ ! -f " $CONFIG_DIR /config.yml " ] ] ; then
sed \
-e " s/CHANGE_ME_DB_PASSWORD/ $DB_PASSWORD /g " \
-e " s/CHANGE_ME_64_CHAR_SECRET/ $API_SECRET /g " \
-e " s/mail\.example\.com/ $FQDN /g " \
" $INSTALL_DIR /config/config.docker.yml.example " \
> " $CONFIG_DIR /config.yml "
chmod 640 " $CONFIG_DIR /config.yml "
log " config.yml erstellt: $CONFIG_DIR /config.yml "
else
log "config.yml existiert bereits – wird nicht überschrieben"
fi
# ── .env für docker-compose ───────────────────────────────────────────────
info "Erstelle .env..."
if [ [ ! -f " $INSTALL_DIR /.env " ] ] ; then
printf 'DB_PASSWORD=%s\n' " $DB_PASSWORD " > " $INSTALL_DIR /.env "
chmod 600 " $INSTALL_DIR /.env "
log ".env erstellt"
else
log ".env existiert bereits – wird nicht überschrieben"
fi
# ── deploy.sh ausführbar ──────────────────────────────────────────────────
chmod +x " $INSTALL_DIR /scripts/deploy.sh "
# ── logrotate ─────────────────────────────────────────────────────────────
cat > /etc/logrotate.d/archivmail <<EOF
${LOG_DIR}/deploy.log {
weekly
rotate 12
compress
delaycompress
missingok
notifempty
}
EOF
log "logrotate konfiguriert"
# ── webhook systemd-Dienst ────────────────────────────────────────────────
info "Richte webhook-Dienst ein..."
cat > /etc/systemd/system/archivmail-webhook.service <<EOF
[Unit]
Description=archivmail GitHub Webhook Receiver
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=$INSTALL_DIR
Environment="WEBHOOK_SECRET=$WEBHOOK_SECRET"
Environment="INSTALL_DIR=$INSTALL_DIR"
ExecStart=/usr/local/bin/webhook \\
-hooks $INSTALL_DIR/scripts/webhook-hooks.json \\
-port 9000 \\
-ip 127.0.0.1 \\
-verbose
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now archivmail-webhook
log "archivmail-webhook Dienst gestartet"
# ── nginx ─────────────────────────────────────────────────────────────────
info "Konfiguriere nginx..."
cat > /etc/nginx/sites-available/archivmail <<EOF
# HTTP → HTTPS Redirect
server {
listen 80;
server_name ${FQDN} _;
return 301 https://\$host\$request_uri;
}
# HTTPS
server {
listen 443 ssl;
http2 on;
server_name ${FQDN} _;
ssl_certificate ${SSL_DIR}/archivmail.crt;
ssl_certificate_key ${SSL_DIR}/archivmail.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
add_header Strict-Transport-Security "max-age=31536000" always;
add_header X-Content-Type-Options nosniff always;
add_header X-Frame-Options SAMEORIGIN always;
# GitHub Webhook
location /hooks/ {
proxy_pass http://127.0.0.1:9000/hooks/;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_read_timeout 30s;
}
# Go API
location /api/ {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
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_set_header X-Forwarded-Proto \$scheme;
client_max_body_size 512M;
}
# Next.js Frontend
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_set_header X-Forwarded-Proto \$scheme;
}
access_log /var/log/nginx/archivmail.access.log;
error_log /var/log/nginx/archivmail.error.log;
}
EOF
ln -sf /etc/nginx/sites-available/archivmail /etc/nginx/sites-enabled/archivmail
rm -f /etc/nginx/sites-enabled/default
nginx -t && systemctl enable --now nginx && systemctl reload nginx
log "nginx konfiguriert"
# ── Docker Compose Stack starten ──────────────────────────────────────────
info "Baue und starte Docker Compose Stack..."
cd " $INSTALL_DIR "
docker compose up -d --build
log "Stack gestartet"
# ── Zusammenfassung speichern ─────────────────────────────────────────────
local summary_file = " $CONFIG_DIR /install-summary.txt "
cat > " $summary_file " <<EOF
archivmail Docker-Installation — $(date '+%d.%m.%Y %H:%M:%S')
Server: $FQDN
=== ZUGANGSDATEN ===
Datenbank (PostgreSQL im Container):
Passwort: $DB_PASSWORD
API-Secret (JWT + AES):
Secret: $API_SECRET
GitHub Webhook:
Secret: $WEBHOOK_SECRET
Web-Logins werden beim ersten Container-Start angelegt.
Passwörter: docker logs archivmail | grep -E 'admin|auditor'
=== DIENSTE ===
Web: https://$FQDN
SMTP: $FQDN:2525
IMAP: $FQDN:1143 (nginx → TLS)
=== GITHUB WEBHOOK EINRICHTEN ===
URL: https://$FQDN/hooks/deploy
Content-Type: application/json
Secret: $WEBHOOK_SECRET
Events: Just the push event (refs/heads/main)
=== DATEIPFADE ===
Konfiguration: $CONFIG_DIR/config.yml
Keyfile: $CONFIG_DIR/keyfile (NIEMALS löschen!)
TLS-Cert: $SSL_DIR/archivmail.crt
Repository: $INSTALL_DIR
Deploy-Log: $LOG_DIR/deploy.log
=== NÜTZLICHE BEFEHLE ===
docker compose -f $INSTALL_DIR/docker-compose.yml logs -f
docker compose -f $INSTALL_DIR/docker-compose.yml ps
bash $INSTALL_DIR/scripts/deploy.sh # Manueller Deploy
EOF
chmod 600 " $summary_file "
log " Zusammenfassung: $summary_file "
# ── Abschluss ─────────────────────────────────────────────────────────────
echo ""
echo " ╔══════════════════════════════════════════════════════════════╗"
echo " ║ Docker-Installation abgeschlossen! ║"
echo " ╚══════════════════════════════════════════════════════════════╝"
echo ""
log " archivmail läuft unter: https:// $FQDN "
echo ""
warn "GitHub Webhook jetzt einrichten:"
echo " URL: https:// $FQDN /hooks/deploy "
echo " Content-Type: application/json"
echo " Secret: $WEBHOOK_SECRET "
echo " Events: Push (nur main-Branch)"
echo ""
warn "Initial-Passwörter: docker logs archivmail | grep -E 'admin|auditor'"
warn " Zusammenfassung: $CONFIG_DIR /install-summary.txt "
echo ""
}
# ══════════════════════════════════════════════════════════════════════════════
# NATIVE INSTALLATION (systemd, direkter Build)
# ══════════════════════════════════════════════════════════════════════════════
install_native( ) {
# ── 1. Pakete ─────────────────────────────────────────────────────────────
info "Installiere Systempakete..."
apt-get update -qq
apt-get install -y -qq \
@@ -52,13 +399,13 @@ if ! command -v go >/dev/null 2>&1; then
fi
log " go $( go version | awk '{print $3}' ) "
# ── 2. Systembenutzer ──── ─────────────────────────────────────────────────────
# ── 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 ──── ────────────────────────────────────────────────
# ── 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 " " $SSL_DIR "
@@ -67,7 +414,7 @@ chmod 755 "$STORE_DIR"
chmod 700 " $STORE_DIR /store " " $STORE_DIR /astore " " $STORE_DIR /xapian "
log "Verzeichnisse erstellt"
# ── 4. Keyfile ──── ────────────────────────────────────────────────────────────
# ── 4. Keyfile ────────────────────────────────────────────────────────────
info "Generiere Verschlüsselungs-Keyfile..."
if [ ! -f " $CONFIG_DIR /keyfile " ] ; then
openssl rand -base64 32 > " $CONFIG_DIR /keyfile "
@@ -78,7 +425,7 @@ else
log "Keyfile existiert bereits – wird nicht überschrieben"
fi
# ── 5. TLS-Zertifikat ──── ─────────────────────────────────────────────────────
# ── 5. TLS-Zertifikat ─────────────────────────────────────────────────────
info "Erstelle selbstsigniertes TLS-Zertifikat..."
if [ ! -f " $SSL_DIR /archivmail.crt " ] ; then
SERVER_IP = " $( hostname -I | awk '{print $1}' ) "
@@ -96,7 +443,7 @@ else
log "TLS-Zertifikat existiert bereits – wird nicht überschrieben"
fi
# ── 6. PostgreSQL ──── ─────────────────────────────────────────────────────────
# ── 6. PostgreSQL ─────────────────────────────────────────────────────────
info "Richte PostgreSQL ein..."
systemctl enable postgresql --quiet
systemctl start postgresql
@@ -112,16 +459,13 @@ su -c "psql -tc \"SELECT 1 FROM pg_roles WHERE rolname='archivmail'\" | grep -q
|| 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 eingerichtet"
log "Standard-Benutzer werden beim ersten Daemon-Start angelegt"
# ── 7. Konfiguration ──── ──────────────────────────────────────────────────────
# ── 7. Konfiguration ──────────────────────────────────────────────────────
info "Erstelle Konfigurationsdatei..."
if [ ! -f " $CONFIG_DIR /config.yml " ] ; then
cat > " $CONFIG_DIR /config.yml " << CONFIG
@@ -182,8 +526,8 @@ else
log "config.yml existiert bereits – wird nicht überschrieben"
fi
# ── 8. Nginx (HTTP + HTTPS) ────────────────────────────────────────────────────
info "Konfiguriere N ginx (HTTP → HTTPS Redirect + TLS)..."
# ── 8. Nginx ────────── ────────────────────────────────────────────────────
info "Konfiguriere n ginx (HTTP → HTTPS + TLS)..."
cat > /etc/nginx/sites-available/archivmail << NGINX
# HTTP → HTTPS Redirect
server {
@@ -241,9 +585,9 @@ rm -f /etc/nginx/sites-enabled/default
nginx -t
systemctl enable nginx --quiet
systemctl restart nginx
log "N ginx konfiguriert (HTTP→HTTPS, TLS) "
log "n ginx konfiguriert"
# ── 9. logrotate ──── ──────────────────────────────────────────────────────────
# ── 9. logrotate ──────────────────────────────────────────────────────────
cat > /etc/logrotate.d/archivmail << LOGROTATE
${LOG_DIR}/audit.log {
daily
@@ -257,7 +601,7 @@ ${LOG_DIR}/audit.log {
LOGROTATE
log "logrotate konfiguriert"
# ── 10. systemd Units ──── ─────────────────────────────────────────────────────
# ── 10. systemd Units ─────────────────────────────────────────────────────
info "Erstelle systemd Units..."
cat > /etc/systemd/system/archivmail.service << UNIT
[Unit]
@@ -314,18 +658,24 @@ systemctl daemon-reload
systemctl enable archivmail archivmail-web --quiet
log "systemd Units erstellt und aktiviert"
# ── 11. update.sh installieren und erstes Deployment ──────────────────────────
# ── 11. Erstes Deployment via update.sh ───────── ──────────────────────────
info "Installiere update.sh und führe erstes Deployment durch..."
curl -fsSL " ${ REPO_URL / \. git / } /raw/branch/main/update.sh " -o " $INSTALL_DIR /update.sh " 2>/dev/null \
|| { warn "update.sh konnte nicht von Gitea geladen werden – überspringe Deployment" ; }
_update_url = " ${ REPO_URL / \. git / } /raw/branch/main/update.sh "
# GitHub-URLs anpassen (raw.githubusercontent.com statt github.com/raw/...)
if [ [ " $REPO_URL " = = *"github.com" * ] ] ; then
_repo_path = " ${ REPO_URL #*github.com/ } "
_repo_path = " ${ _repo_path %.git } "
_update_url = " https://raw.githubusercontent.com/ ${ _repo_path } /main/update.sh "
fi
curl -fsSL " $_update_url " -o " $INSTALL_DIR /update.sh " 2>/dev/null \
|| { warn "update.sh konnte nicht geladen werden – überspringe Deployment" ; }
if [ -f " $INSTALL_DIR /update.sh " ] ; then
chmod +x " $INSTALL_DIR /update.sh "
log " update.sh installiert: $INSTALL_DIR /update.sh "
info "Führe erstes Deployment durch (Build + Start) ..."
log "update.sh installiert"
info "Führe erstes Deployment durch..."
bash " $INSTALL_DIR /update.sh "
# Echte Passwörter aus Journal lesen (Backend gibt sie beim ersten Start aus)
# Auf Backend warten (bis zu 15 Sekunden)
for _i in $( seq 1 15) ; do
_pw = $( journalctl -u archivmail --no-pager -n 100 | grep 'admin' | grep -oP ':\s+\K[0-9a-f]{16,}' | tail -1)
[ [ -n " $_pw " ] ] && break
@@ -334,42 +684,29 @@ if [ -f "$INSTALL_DIR/update.sh" ]; then
PW_SUPERADMIN = $( journalctl -u archivmail --no-pager -n 100 | grep 'superadmin' | grep -oP ':\s+\K\S+' | tail -1)
PW_ADMIN = $( journalctl -u archivmail --no-pager -n 100 | grep ' admin ' | grep -v superadmin | grep -oP ':\s+\K\S+' | tail -1)
PW_AUDITOR = $( journalctl -u archivmail --no-pager -n 100 | grep 'auditor' | grep -oP ':\s+\K\S+' | tail -1)
[ [ -n " $PW_ADMIN " ] ] || PW_ADMIN = "(nicht gefunden — siehe: journalctl -u archivmail | grep admin)"
[ [ -n " $PW_AUDITOR " ] ] || PW_AUDITOR = "(nicht gefunden — siehe: journalctl -u archivmail | grep auditor)"
[ [ -n " $PW_SUPERADMIN " ] ] || PW_SUPERADMIN = "(nicht gefunden — siehe: journalctl -u archivmail | grep superadmin)"
[ [ -n " $PW_ADMIN " ] ] || PW_ADMIN = "(nicht gefunden — journalctl -u archivmail | grep admin)"
[ [ -n " $PW_AUDITOR " ] ] || PW_AUDITOR = "(nicht gefunden — journalctl -u archivmail | grep auditor)"
[ [ -n " $PW_SUPERADMIN " ] ] || PW_SUPERADMIN = "(nicht gefunden — journalctl -u archivmail | grep superadmin)"
else
warn " update.sh fehlt — manuell ausführen : bash $INSTALL_DIR /update.sh "
PW_SUPERADMIN = "(noch nicht generiert)"
PW_ADMIN = "(noch nicht generiert)"
PW_AUDITOR = "(noch nicht generiert)"
warn " update.sh fehlt — manuell: bash $INSTALL_DIR /update.sh "
PW_SUPERADMIN = "(noch nicht generiert)" ; PW_ADMIN = "(noch nicht generiert)" ; PW_AUDITOR = "(noch nicht generiert)"
fi
# ── Zusammenfassung in Datei speichern ────────────────────────────────────────
# ── Zusammenfassung ─────────────── ────────────────────────────────────────
SUMMARY_FILE = " $CONFIG_DIR /install-summary.txt "
cat > " $SUMMARY_FILE " << SUMMARY
archivmail Installation — $(date '+%d.%m.%Y %H:%M:%S')
archivmail Native- Installation — $(date '+%d.%m.%Y %H:%M:%S')
Server: $FQDN
=== ANGELEGTE BENUTZER & PASSWÖRTER ===
=== ZUGANGSDATEN ===
Systembenutzer (Linux):
Benutzer: $AM_USER
Shell: /bin/false (kein Login)
Home: $STORE_DIR
Datenbank: archivmail / $DB_PASSWORD
API-Secret: $API_SECRET
Datenbank (PostgreSQL ):
Datenbank: archivmail
Benutzer: archivmail
Passwort: $DB_PASSW ORD
Verbindung: 127.0.0.1:5432
API-Secret (JWT + AES-Schlüsselableitung):
Secret: $API_SECRET
Web-Anwendung (UNBEDINGT ÄNDERN!):
Superadmin: superadmin@archivmail / $PW_SUPERADMIN
Admin: admin@archivmail / $PW_ADMIN
Auditor: auditor@archivmail / $PW_AUDITOR
Web-Logins (UNBEDINGT ÄNDERN! ):
superadmin@archivmail / $PW_SUPERADMIN
admin@archivmail / $PW_ADMIN
auditor@archivmail / $PW_AUDIT OR
=== DIENSTE ===
@@ -382,38 +719,22 @@ Server: $FQDN
Konfiguration: $CONFIG_DIR/config.yml
Keyfile: $CONFIG_DIR/keyfile
TLS-Zertifikat: $SSL_DIR/archivmail.crt
TLS-Schlüssel: $SSL_DIR/archivmail.key
Mail-Speicher: $STORE_DIR/
Logs: $LOG_DIR/
Updater: $INSTALL_DIR/update.sh
=== HINWEISE ===
- Das TLS-Zertifikat ist selbstsigniert (10 Jahre gültig).
Im Browser: Ausnahme hinzufügen oder Zertifikat importieren.
Für vertrauenswürdiges Zertifikat: Admin → Zertifikat → Let's Encrypt
- DB-Passwort und API-Secret stehen in $CONFIG_DIR/config.yml (chmod 640).
- Keyfile NIEMALS löschen oder überschreiben — alle Mails werden damit entschlüsselt.
- Diese Datei nach dem ersten Login löschen oder sicher aufbewahren!
SUMMARY
chmod 600 " $SUMMARY_FILE "
log " Zusammenfassung gespeichert : $SUMMARY_FILE "
log " Zusammenfassung: $SUMMARY_FILE "
# ── Abschlussbericht ──────────────────────────────────────────────────────────
# ── Abschluss ─── ──────────────────────────────────────────────────────────
echo ""
echo " ╔══════════════════════════════════════════════════════════╗"
echo " ║ Installation abgeschlossen! ║"
echo " ╚══════════════════════════════════════════════════════════╝"
echo ""
echo " Hostname (FQDN): $FQDN "
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 " TLS-Zertifikat: $SSL_DIR /archivmail.crt "
echo " Logs: $LOG_DIR / "
echo " Web (HTTPS): https:// $FQDN "
echo " IMAP (TLS): $FQDN :993 "
echo " SMTP: $FQDN :2525 "
echo ""
echo " ┌─────────────────────────────────────────────────────────┐"
echo " │ ANGELEGTE BENUTZER & PASSWÖRTER │"
@@ -424,20 +745,17 @@ echo " │ Web-Logins (UNBEDINGT ÄNDERN!): │"
printf " │ superadmin / %-38s│\n" " $PW_SUPERADMIN "
printf " │ admin / %-38s│\n" " $PW_ADMIN "
printf " │ auditor / %-38s│\n" " $PW_AUDITOR "
echo " ├─────────────────────────────────────────────────────────┤"
printf " │ API-Secret: %-38s │\n" " ${ API_SECRET : 0 : 38 } "
echo " └─────────────────────────────────────────────────────────┘"
echo ""
echo " Vollständige Zusammenfassung : $SUMMARY_FILE "
echo ""
echo " Dienste:"
echo " Web (HTTPS): https:// $FQDN "
echo " IMAP (TLS): $FQDN :993 "
echo " SMTP: $FQDN :2525 "
echo ""
echo " Hinweis: Das TLS-Zertifikat ist selbstsigniert."
echo " Für ein vertrauenswürdiges Zertifikat: Admin → Zertifikat → Let's Encrypt"
echo ""
warn " Zusammenfassung mit Passwörtern: $SUMMARY_FILE (chmod 600) "
warn " Zusammenfassung mit Passwörtern : $SUMMARY_FILE "
warn "Standardpasswörter unbedingt nach dem ersten Login ändern!"
echo ""
}
# ══════════════════════════════════════════════════════════════════════════════
# MODUS AUSFÜHREN
# ══════════════════════════════════════════════════════════════════════════════
case " $INSTALL_MODE " in
docker) install_docker ; ;
native) install_native ; ;
esac