| Server IP : 138.197.107.151 / Your IP : 216.73.217.7 Web Server : Apache/2.4.58 (Ubuntu) System : Linux BloxBy-Builder 6.8.0-71-generic #71-Ubuntu SMP PREEMPT_DYNAMIC Tue Jul 22 16:52:38 UTC 2025 x86_64 User : wpbetasites_mrakzqskir ( 1022) PHP Version : 8.3.6 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/bsd-crawler-parser/ |
Upload File : |
#!/usr/bin/env bash
#
# Removes public read access from the bsd-wpe-logs bucket.
#
# !!! DO NOT RUN THIS SCRIPT !!!
# WP Engine support confirmed bsd-wpe-logs must stay public for log delivery.
# Running this WILL break log ingestion. It is kept only as a record of what
# was considered, and because bsd-wpe-logs-policy.backup.json is a useful
# snapshot of the live policy. See the README section "bsd-wpe-logs is public,
# by decision".
#
# ./fix-public-bucket.sh # DRY RUN - prints what it would do
# ./fix-public-bucket.sh --apply # actually make the change
# ./fix-public-bucket.sh --rollback # restore the original public policy
#
# WHAT THIS CHANGES
# Removes the "PublicReadObjectsOnly" statement, which currently grants
# s3:GetObject to Principal "*" (anyone on the internet), and turns on all
# four public access blocks.
#
# WHAT THIS KEEPS
# The "AllowWpeLogsBackup" statement is preserved byte-for-byte. WP Engine
# delivers logs as the named IAM principal
# arn:aws:iam::902500896138:user/wpengine-remote-logs, which has its own
# explicit ListBucket/GetObject/PutObject grant. It does not rely on the
# public statement, so delivery should be unaffected.
#
# THE RISK, STATED PLAINLY
# "Should be unaffected" is an inference from the policy, not something that
# has been observed. If WP Engine's log shipper depends on anonymous access
# in some way not visible in the policy, log delivery stops and the parser
# goes quiet. Verify with step 4 below, and roll back if the sweep stops
# moving objects.
#
# HOW TO VERIFY AFTER APPLYING
# 1. get-bucket-policy-status should report IsPublic: false (checked below)
# 2. Watch for the next WP Engine drop (~00:17 UTC daily) and confirm the
# sweep still reports "Moved N objects" with N > 0:
# aws logs tail /aws/lambda/wpe-log-sweep --region us-east-1 --since 1h
# 3. If nothing arrives for a full day, roll back and contact WP Engine.
#
set -euo pipefail
if [[ "${I_KNOW_THIS_BREAKS_LOG_DELIVERY:-}" != "yes" ]]; then
echo "refusing to run: WP Engine requires bsd-wpe-logs to stay public." >&2
echo "see README -> \"bsd-wpe-logs is public, by decision\"" >&2
exit 1
fi
BUCKET="bsd-wpe-logs"
REGION="us-east-1"
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BACKUP="$HERE/bsd-wpe-logs-policy.backup.json"
PROPOSED="$HERE/bsd-wpe-logs-policy.proposed.json" # regenerated on demand; see README - do NOT run this script
MODE="dry-run"
case "${1:-}" in
--apply) MODE="apply" ;;
--rollback) MODE="rollback" ;;
"") MODE="dry-run" ;;
*) echo "usage: $0 [--apply|--rollback]" >&2; exit 2 ;;
esac
status() {
local s
s=$(aws s3api get-bucket-policy-status --bucket "$BUCKET" --region "$REGION" \
--query 'PolicyStatus.IsPublic' --output text 2>/dev/null || echo "unknown")
echo " bucket-policy-status IsPublic = $s"
}
if [[ "$MODE" == "rollback" ]]; then
[[ -f "$BACKUP" ]] || { echo "missing $BACKUP" >&2; exit 1; }
echo "!! restoring the ORIGINAL PUBLIC policy from $BACKUP"
read -r -p " this makes the bucket world-readable again. type YES: " c
[[ "$c" == "YES" ]] || { echo "aborted"; exit 1; }
aws s3api delete-public-access-block --bucket "$BUCKET" --region "$REGION"
aws s3api put-bucket-policy --bucket "$BUCKET" --region "$REGION" \
--policy "file://$BACKUP"
echo "rolled back."
status
exit 0
fi
echo "bucket: $BUCKET"
echo "backup: $BACKUP"
echo "proposed: $PROPOSED"
echo
echo "current state:"
status
echo
echo "current policy statements:"
aws s3api get-bucket-policy --bucket "$BUCKET" --region "$REGION" \
--query 'Policy' --output text | python3 -c \
'import json,sys; [print(" - %s -> Principal %s" % (s["Sid"], json.dumps(s["Principal"]))) for s in json.load(sys.stdin)["Statement"]]'
echo
echo "proposed policy statements:"
python3 -c \
'import json,sys; [print(" - %s -> Principal %s" % (s["Sid"], json.dumps(s["Principal"]))) for s in json.load(open(sys.argv[1]))["Statement"]]' "$PROPOSED"
echo
if [[ "$MODE" == "dry-run" ]]; then
# Paths are quoted below because this directory name contains spaces and
# these lines are meant to be copy-pasteable.
cat <<EOF
DRY RUN - nothing changed. To apply, these two commands would run:
aws s3api put-bucket-policy --bucket $BUCKET --region $REGION \\
--policy "file://$PROPOSED"
aws s3api put-public-access-block --bucket $BUCKET --region $REGION \\
--public-access-block-configuration \\
BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true
Re-run with --apply to do it, or --rollback to undo it later.
EOF
exit 0
fi
# --- apply -----------------------------------------------------------------
[[ -f "$PROPOSED" ]] || { echo "missing $PROPOSED" >&2; exit 1; }
[[ -f "$BACKUP" ]] || { echo "missing $BACKUP (refusing to proceed without a rollback)" >&2; exit 1; }
read -r -p "apply the fix to $BUCKET? type YES: " c
[[ "$c" == "YES" ]] || { echo "aborted"; exit 1; }
# Policy first, then the block. If the second step fails, the bucket is
# already non-public rather than half-configured.
echo "[+] replacing bucket policy (drops PublicReadObjectsOnly)"
aws s3api put-bucket-policy --bucket "$BUCKET" --region "$REGION" \
--policy "file://$PROPOSED"
echo "[+] enabling all four public access blocks"
aws s3api put-public-access-block --bucket "$BUCKET" --region "$REGION" \
--public-access-block-configuration \
"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
echo
echo "new state:"
status
echo
echo "Now confirm WP Engine delivery still works (next drop ~00:17 UTC):"
echo " aws logs tail /aws/lambda/wpe-log-sweep --region $REGION --since 1h"
echo "If no logs arrive for a full day: $0 --rollback"