Harden quarantine provisioning; enforce strict permissions and update Ansible and docs

This commit is contained in:
2026-02-12 07:47:48 +01:00
parent 037b176892
commit 1768f61da1
44 changed files with 2587 additions and 698 deletions

104
scripts/provision_dirs.sh Normal file
View File

@@ -0,0 +1,104 @@
#!/usr/bin/env bash
set -euo pipefail
# Provision quarantine and state directories for upload-logger
# Usage: sudo ./provision_dirs.sh [--config path/to/upload-logger.json]
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
CFG="${1:-$ROOT_DIR/upload-logger.json}"
QUIET=0
if [[ "${2:-}" == "--quiet" ]]; then QUIET=1; fi
info(){ if [[ $QUIET -ne 1 ]]; then echo "[INFO] $*"; fi }
err(){ echo "[ERROR] $*" >&2; }
if [[ $EUID -ne 0 ]]; then
err "This script must be run as root to set ownership and SELinux contexts."
err "Rerun as: sudo $0"
exit 2
fi
# Defaults
QUARANTINE_DIR_DEFAULT="$ROOT_DIR/quarantine"
STATE_DIR_DEFAULT="$ROOT_DIR/state"
QUARANTINE_OWNER_DEFAULT="root"
QUARANTINE_GROUP_DEFAULT="www-data"
QUARANTINE_PERMS_DEFAULT="0700"
STATE_PERMS_DEFAULT="0750"
SELINUX_FCONTEXT_DEFAULT="httpd_sys_rw_content_t"
QUARANTINE_DIR="$QUARANTINE_DIR_DEFAULT"
STATE_DIR="$STATE_DIR_DEFAULT"
QUARANTINE_OWNER="$QUARANTINE_OWNER_DEFAULT"
QUARANTINE_GROUP="$QUARANTINE_GROUP_DEFAULT"
QUARANTINE_PERMS="$QUARANTINE_PERMS_DEFAULT"
STATE_PERMS="$STATE_PERMS_DEFAULT"
SELINUX_FCONTEXT="$SELINUX_FCONTEXT_DEFAULT"
if [[ -f "$CFG" ]]; then
info "Loading config from $CFG"
# Use jq-like parsing with grep/sed to avoid requiring jq on systems
QUARANTINE_DIR=$(grep -oP '"quarantine_dir"\s*:\s*"\K[^"]+' "$CFG" || echo "$QUARANTINE_DIR")
STATE_DIR=$(grep -oP '"state_dir"\s*:\s*"\K[^"]+' "$CFG" || echo "$STATE_DIR")
QUARANTINE_PERMS=$(grep -oP '"quarantine_dir_perms"\s*:\s*"\K[^"]+' "$CFG" || echo "$QUARANTINE_PERMS")
QUARANTINE_OWNER=$(grep -oP '"quarantine_owner"\s*:\s*"\K[^"]+' "$CFG" || echo "$QUARANTINE_OWNER")
QUARANTINE_GROUP=$(grep -oP '"quarantine_group"\s*:\s*"\K[^"]+' "$CFG" || echo "$QUARANTINE_GROUP")
fi
info "Ensuring directories exist"
mkdir -p -- "$QUARANTINE_DIR"
mkdir -p -- "$STATE_DIR"
info "Setting permissions and ownership"
chmod ${QUARANTINE_PERMS} "$QUARANTINE_DIR" || true
chown ${QUARANTINE_OWNER}:${QUARANTINE_GROUP} "$QUARANTINE_DIR" || true
chmod ${STATE_PERMS} "$STATE_DIR" || true
chown ${QUARANTINE_OWNER}:${QUARANTINE_GROUP} "$STATE_DIR" || true
# Ensure existing files in quarantine are not world-readable/executable.
if [[ -d "$QUARANTINE_DIR" ]]; then
info "Hardening existing files in $QUARANTINE_DIR"
# Set files to 0600 and directories to 0700
find "$QUARANTINE_DIR" -type d -print0 | xargs -0 -r chmod 0700 || true
find "$QUARANTINE_DIR" -type f -print0 | xargs -0 -r chmod 0600 || true
chown -R ${QUARANTINE_OWNER}:${QUARANTINE_GROUP} "$QUARANTINE_DIR" || true
fi
info "Verifying permissions"
ls -ld "$QUARANTINE_DIR" "$STATE_DIR"
# SELinux handling (best-effort)
if command -v getenforce >/dev/null 2>&1 && [[ "$(getenforce)" != "Disabled" ]]; then
info "SELinux enabled on system; attempting to configure file context"
if command -v semanage >/dev/null 2>&1; then
info "Registering fcontext for $QUARANTINE_DIR -> $SELINUX_FCONTEXT"
semanage fcontext -a -t ${SELINUX_FCONTEXT} "${QUARANTINE_DIR}(/.*)?" || true
info "Registering fcontext for $STATE_DIR -> ${SELINUX_FCONTEXT}"
semanage fcontext -a -t ${SELINUX_FCONTEXT} "${STATE_DIR}(/.*)?" || true
info "Applying contexts with restorecon"
restorecon -Rv "$QUARANTINE_DIR" "$STATE_DIR" || true
else
info "semanage not available; skipping fcontext registration. Install policycoreutils-python-utils or provide manual guidance."
fi
else
info "SELinux not enabled or getenforce unavailable; skipping SELinux steps"
fi
# Optional tmpfiles.d entry to recreate directories at boot (idempotent)
TMPFILE="/etc/tmpfiles.d/upload-logger.conf"
if [[ -w /etc/tmpfiles.d || $QUIET -eq 1 ]]; then
info "Writing tmpfiles.d entry to ${TMPFILE}"
cat > "$TMPFILE" <<EOF
d ${QUARANTINE_DIR} ${QUARANTINE_PERMS} ${QUARANTINE_OWNER} ${QUARANTINE_GROUP} -
d ${STATE_DIR} ${STATE_PERMS} ${QUARANTINE_OWNER} ${QUARANTINE_GROUP} -
EOF
else
info "Skipping tmpfiles.d entry (no permission to write /etc/tmpfiles.d)"
fi
info "Provisioning complete. Ensure PHP-FPM worker user can write to the state directory if needed."
echo
info "Summary:"
stat -c "%U:%G %a %n" "$QUARANTINE_DIR" "$STATE_DIR" || true
exit 0