105 lines
4.1 KiB
Bash
105 lines
4.1 KiB
Bash
#!/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
|