#!/usr/bin/env bash
# wp-fim.sh, server-side file integrity monitor for a single WordPress install.
# Source: https://techearl.com/wordpress-file-integrity-monitoring-server-side
# Site:   https://techearl.com/
# Runs as root from cron. Stores baseline in /var/lib/wp-fim/ (out of WordPress's reach).
# Alerts via OS mail when anything in WATCH_PATHS changes from the baseline.

set -e
WP_ROOT="/var/www/wordpress"
ALERT_EMAIL="alerts@your-off-server-address.com"
HOSTNAME=$(hostname -f 2>/dev/null || hostname)
BASELINE_DIR="/var/lib/wp-fim"
mkdir -p "$BASELINE_DIR"

# Paths to monitor. wp-content/uploads/ is excluded because legitimate uploads
# change frequently; we monitor whether PHP appears there separately.
WATCH_PATHS=(
  "$WP_ROOT/wp-config.php"
  "$WP_ROOT/.htaccess"
  "$WP_ROOT/index.php"
  "$WP_ROOT/wp-admin"
  "$WP_ROOT/wp-includes"
  "$WP_ROOT/wp-content/plugins"
  "$WP_ROOT/wp-content/themes"
  "$WP_ROOT/wp-content/mu-plugins"
)

# 1. Compute the current state
CURRENT="$BASELINE_DIR/current.txt"
> "$CURRENT"
for p in "${WATCH_PATHS[@]}"; do
  [ -e "$p" ] || continue
  if [ -d "$p" ]; then
    find "$p" -type f \( -name '*.php' -o -name '*.htaccess' -o -name '*.js' \) \
      -exec sha256sum {} \; >> "$CURRENT" 2>/dev/null
  else
    sha256sum "$p" >> "$CURRENT" 2>/dev/null
  fi
done

# 2. Also catch the "PHP appeared in uploads" case (always suspicious)
SUSPICIOUS_UPLOADS=$(find "$WP_ROOT/wp-content/uploads" -type f -name '*.php' 2>/dev/null)

# 3. Compare to baseline (first run creates the baseline)
BASELINE="$BASELINE_DIR/baseline.txt"
if [ ! -f "$BASELINE" ]; then
  cp "$CURRENT" "$BASELINE"
  echo "Initial baseline created at $BASELINE." | mail -s "wp-fim baseline created on $HOSTNAME" "$ALERT_EMAIL"
  exit 0
fi

DIFF=$(diff "$BASELINE" "$CURRENT" || true)

if [ -n "$DIFF" ] || [ -n "$SUSPICIOUS_UPLOADS" ]; then
  {
    echo "WordPress file integrity anomaly on $HOSTNAME at $(date)."
    echo
    if [ -n "$SUSPICIOUS_UPLOADS" ]; then
      echo "PHP files found in wp-content/uploads (always suspicious):"
      echo "$SUSPICIOUS_UPLOADS"
      echo
    fi
    if [ -n "$DIFF" ]; then
      echo "Hash differences from baseline:"
      echo "$DIFF" | head -200
    fi
  } | mail -s "ALERT: wp-fim integrity anomaly on $HOSTNAME" "$ALERT_EMAIL"
fi
