Fix: Backup läuft als root via sudo – keine Permission-Fehler mehr
mailwolt-backup Script liest /etc/dovecot/private, /etc/letsencrypt/live etc. als root. ensure_system() installiert es nach sbin + sudoers. BackupRun.php ruft es via sudo -n auf. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>main v1.1.346
parent
7e7d5c1069
commit
de314adebe
|
|
@ -28,7 +28,7 @@ class BackupRun extends Command
|
|||
$script = '/usr/local/sbin/mailwolt-backup';
|
||||
if (file_exists($script)) {
|
||||
$output = [];
|
||||
exec("bash " . escapeshellarg($script) . ' 2>&1', $output, $exitCode);
|
||||
exec('sudo -n ' . escapeshellarg($script) . ' 2>&1', $output, $exitCode);
|
||||
|
||||
$artifact = null;
|
||||
foreach ($output as $line) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
#!/usr/bin/env bash
|
||||
# Mailwolt Backup – läuft als root via sudo, liest DB-Credentials aus .env
|
||||
set -euo pipefail
|
||||
|
||||
APP_DIR="/var/www/mailwolt"
|
||||
APP_USER="www-data"
|
||||
OUT_DIR="${APP_DIR}/storage/app/backups"
|
||||
STAMP="$(date +%Y-%m-%d_%H-%M-%S)"
|
||||
OUT_FILE="${OUT_DIR}/mailwolt_${STAMP}.tar.gz"
|
||||
TMP_DIR="$(mktemp -d /tmp/mailwolt_backup_XXXXXX)"
|
||||
|
||||
cleanup(){ rm -rf "$TMP_DIR"; }
|
||||
trap cleanup EXIT
|
||||
|
||||
mkdir -p "$OUT_DIR"
|
||||
chown "${APP_USER}:${APP_USER}" "$OUT_DIR" 2>/dev/null || true
|
||||
|
||||
# ── Datenbank ──────────────────────────────────────────────────────────────
|
||||
ENV_FILE="${APP_DIR}/.env"
|
||||
DB_HOST="127.0.0.1"; DB_PORT="3306"; DB_USER=""; DB_PASS=""; DB_NAME=""
|
||||
if [[ -f "$ENV_FILE" ]]; then
|
||||
DB_HOST="$(grep '^DB_HOST=' "$ENV_FILE" | head -1 | cut -d= -f2- | tr -d '"' | tr -d "'")"
|
||||
DB_PORT="$(grep '^DB_PORT=' "$ENV_FILE" | head -1 | cut -d= -f2- | tr -d '"' | tr -d "'")"
|
||||
DB_USER="$(grep '^DB_USERNAME=' "$ENV_FILE" | head -1 | cut -d= -f2- | tr -d '"' | tr -d "'")"
|
||||
DB_PASS="$(grep '^DB_PASSWORD=' "$ENV_FILE" | head -1 | cut -d= -f2- | tr -d '"' | tr -d "'")"
|
||||
DB_NAME="$(grep '^DB_DATABASE=' "$ENV_FILE" | head -1 | cut -d= -f2- | tr -d '"' | tr -d "'")"
|
||||
fi
|
||||
|
||||
DUMP_FILE="${TMP_DIR}/database.sql"
|
||||
if [[ -n "$DB_NAME" ]]; then
|
||||
MYSQL_PWD="$DB_PASS" mysqldump \
|
||||
-h "${DB_HOST:-127.0.0.1}" -P "${DB_PORT:-3306}" \
|
||||
-u "$DB_USER" \
|
||||
--single-transaction --routines --triggers \
|
||||
"$DB_NAME" > "$DUMP_FILE" 2>&1
|
||||
echo "✓ Datenbank gesichert"
|
||||
else
|
||||
echo "✗ DB_DATABASE nicht in .env gefunden"
|
||||
fi
|
||||
|
||||
# ── Quellen sammeln ────────────────────────────────────────────────────────
|
||||
SOURCES=("$DUMP_FILE")
|
||||
|
||||
for MAIL_DIR in /var/vmail /var/mail/vhosts /home/vmail; do
|
||||
if [[ -d "$MAIL_DIR" ]]; then
|
||||
SOURCES+=("$MAIL_DIR")
|
||||
echo "✓ Maildirs: $MAIL_DIR"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
for CFG_DIR in /etc/postfix /etc/dovecot /etc/opendkim /etc/rspamd /etc/letsencrypt; do
|
||||
if [[ -d "$CFG_DIR" ]]; then
|
||||
SOURCES+=("$CFG_DIR")
|
||||
echo "✓ $CFG_DIR"
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ -f "${APP_DIR}/.env" ]]; then
|
||||
SOURCES+=("${APP_DIR}/.env")
|
||||
echo "✓ .env"
|
||||
fi
|
||||
|
||||
# ── Archiv erstellen ───────────────────────────────────────────────────────
|
||||
tar --ignore-failed-read -czf "$OUT_FILE" "${SOURCES[@]}" 2>&1 || true
|
||||
|
||||
chown "${APP_USER}:${APP_USER}" "$OUT_FILE" 2>/dev/null || true
|
||||
|
||||
echo "ARTIFACT:${OUT_FILE}"
|
||||
|
|
@ -206,11 +206,13 @@ ensure_system(){
|
|||
_sbin_install "${APP_DIR}/scripts/mailwolt-fetch-tags" /usr/local/sbin/mailwolt-fetch-tags
|
||||
_sbin_install "${APP_DIR}/scripts/update.sh" /usr/local/sbin/mailwolt-update
|
||||
_sbin_install "${APP_DIR}/scripts/mailwolt-clamav" /usr/local/sbin/mailwolt-clamav
|
||||
_sbin_install "${APP_DIR}/scripts/mailwolt-backup" /usr/local/sbin/mailwolt-backup
|
||||
# Sudoers-Regeln nachrüsten
|
||||
for f in /etc/sudoers.d/mailwolt-certbot /etc/sudoers.d/mailwolt-dkim; do
|
||||
_sudoers_add "$f" 'www-data ALL=(root) NOPASSWD: /usr/local/sbin/mailwolt-fetch-tags'
|
||||
_sudoers_add "$f" 'www-data ALL=(root) NOPASSWD: /usr/local/sbin/mailwolt-update --check-only'
|
||||
_sudoers_add "$f" 'www-data ALL=(root) NOPASSWD: /usr/local/sbin/mailwolt-clamav'
|
||||
_sudoers_add "$f" 'www-data ALL=(root) NOPASSWD: /usr/local/sbin/mailwolt-backup'
|
||||
_sudoers_add "$f" 'www-data ALL=(root) NOPASSWD: /usr/bin/openssl x509 -enddate -noout -in /etc/letsencrypt/live/*/fullchain.pem'
|
||||
done
|
||||
# Laravel Scheduler cron (schedule:run muss jede Minute laufen)
|
||||
|
|
|
|||
Loading…
Reference in New Issue