From 082de8e3b2fe7ade4a6b3c62ed697c94662eeb5b Mon Sep 17 00:00:00 2001 From: Subroto Date: Tue, 13 Oct 2026 09:21:25 +0700 Subject: [PATCH] sync @ 48f8b7f --- deploy/scripts/test-generate.sh | 2 +- deploy/scripts/verify-minio.sh | 43 ++++++++++++++++++++++----------- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/deploy/scripts/test-generate.sh b/deploy/scripts/test-generate.sh index 068ac97..76c984e 100755 --- a/deploy/scripts/test-generate.sh +++ b/deploy/scripts/test-generate.sh @@ -531,7 +531,7 @@ _vm="${DEPLOY_DIR}/scripts/verify-minio.sh" if [[ -x "${_vm}" ]] && bash -n "${_vm}" 2>/dev/null \ && grep -q 'AWS4-HMAC-SHA256' "${_vm}" && grep -q 'list-type' "${_vm}" \ && grep -q 'ListBuckets' "${_vm}" && grep -q '/minio/health/live' "${_vm}" \ - && ! grep -q 'minio/mc' "${_vm}"; then + && grep -q 'User-Agent' "${_vm}" && ! grep -q 'minio/mc' "${_vm}"; then ok "verify-minio.sh: bukti S3_ENDPOINT (Python SigV4) + contoh ≤5 object (tanpa mc)" else bad "verify-minio.sh hilang/tidak lengkap (atau masih memakai mc)" diff --git a/deploy/scripts/verify-minio.sh b/deploy/scripts/verify-minio.sh index 6a68751..d9c6553 100755 --- a/deploy/scripts/verify-minio.sh +++ b/deploy/scripts/verify-minio.sh @@ -17,6 +17,8 @@ # ./scripts/verify-minio.sh --env-file generated/host-state/.env # S3_ENDPOINT=https://minio.corp:9000 S3_INSECURE=1 ./scripts/verify-minio.sh # Dukungan self-signed: set S3_INSECURE=1 (lewati verifikasi TLS). +# Di belakang Cloudflare: User-Agent di-set agar tak diblokir Bot Fight Mode (error 1010); +# timpa bila perlu: S3_UA='aws-sdk-go/1.44' ./scripts/verify-minio.sh # Keluar: 0 = OK (WARN boleh) · 1 = ada FAIL · 2 = argumen salah # ============================================================================= set -uo pipefail @@ -45,6 +47,22 @@ fail() { echo -e " ${FAILC} $1"; FAIL_N=$((FAIL_N + 1)); } warn() { echo -e " ${WARNC} $1"; WARN_N=$((WARN_N + 1)); } info() { echo -e " ${INFOC} $1"; } +# Penyebab singkat dari (kode HTTP, , pesan) — termasuk deteksi Cloudflare (error 1010). +err_hint() { # + local st="$1" code="$2" msg="$3" + case "${msg}" in + *1010*|*[Cc]loudflare*) + echo "Cloudflare memblokir klien ini (Bot Fight Mode, error 1010) — set S3_UA, atau tambah exception/waf-skip di Cloudflare untuk host S3"; return ;; + esac + case "${st}" in + 0) echo "tidak terjangkau (koneksi/DNS/TLS) — cek endpoint/port; self-signed? set S3_INSECURE=1";; + 401) echo "butuh autentikasi";; + 403) echo "kredensial/diakses ditolak${code:+ (${code})} — cek S3_ACCESS_KEY / S3_SECRET_KEY";; + 404) echo "bucket/path tidak ada${code:+ (${code})}";; + *) echo "${code:-HTTP ${st}}";; + esac +} + # ── Konfigurasi (S3_ENDPOINT dilihat CONTAINER; skrip ini di HOST) ─────────── S3_ENDPOINT="${S3_ENDPOINT:-http://minio:9000}" S3_REGION="${S3_REGION:-us-east-1}" @@ -76,6 +94,9 @@ sk = os.environ.get("S3P") or "" region = os.environ.get("S3R") or "us-east-1" bucket = os.environ.get("BUCKET") or "" insecure = os.environ.get("S3_INSECURE") == "1" +# User-Agent: Cloudflare Bot Fight Mode MEMBLOKIR `Python-urllib/*` (error 1010) — +# pakai UA yang jelas & tak masuk daftar bot (bisa ditimpa lewat S3_UA). +ua = os.environ.get("S3_UA") or "sicabe-verify-minio/1.0 (+s3; path-style)" u = urllib.parse.urlparse(ep) scheme = u.scheme or "http" host = u.netloc @@ -107,7 +128,8 @@ def get(path, query=None): url = f"{scheme}://{host}{curi}" + (f"?{cqs}" if cqs else "") req = urllib.request.Request(url, method="GET") for h, v in (("Host", host), ("x-amz-date", amzdate), - ("x-amz-content-sha256", phash), ("Authorization", auth)): + ("x-amz-content-sha256", phash), ("Authorization", auth), + ("User-Agent", ua)): req.add_header(h, v) try: with urllib.request.urlopen(req, timeout=15, context=ctx()) as r: @@ -125,7 +147,9 @@ def errline(st, body): if mode == "health": try: - with urllib.request.urlopen(f"{scheme}://{host}/minio/health/live", timeout=8, context=ctx()) as r: + rq = urllib.request.Request(f"{scheme}://{host}/minio/health/live", method="GET") + rq.add_header("User-Agent", ua) + with urllib.request.urlopen(rq, timeout=8, context=ctx()) as r: print(f"HEALTH|{r.status}") except urllib.error.HTTPError as e: print(f"HEALTH|{e.code}") @@ -158,7 +182,7 @@ PYEOF s3py() { # [maxkey] → stdout MODE="$1" MAXKEY="${2:-}" S3E="${S3_HOST_EP}" S3U="${S3_ACCESS_KEY}" S3P="${S3_SECRET_KEY}" \ - S3R="${S3_REGION}" BUCKET="${BUCKET}" S3_INSECURE="${S3_INSECURE:-0}" python3 "${_PY}" 2>/dev/null + S3R="${S3_REGION}" BUCKET="${BUCKET}" S3_INSECURE="${S3_INSECURE:-0}" S3_UA="${S3_UA:-}" python3 "${_PY}" 2>/dev/null } echo -e "${BOLD}Verifikasi MinIO/S3 — bucket '${BUCKET}'${NC}" @@ -207,14 +231,7 @@ if [[ "${bout}" == BUCKETS\|* ]]; then printf '%s\n' "${bout}" | awk -F'|' '$1=="BUCKET"{printf " • %s\n", $2}' elif [[ "${bout}" == ERR\|* ]]; then IFS='|' read -r _ st code msg <<< "${bout}" - hint="" - case "${st}" in - 0) hint="tidak terjangkau (koneksi/DNS/TLS) — cek endpoint/port; self-signed? set S3_INSECURE=1";; - 403) hint="kredensial/diakses ditolak (cek S3_ACCESS_KEY / S3_SECRET_KEY)";; - 401) hint="butuh autentikasi";; - *) hint="${code:-HTTP ${st}}";; - esac - fail "ListBuckets GAGAL [HTTP ${st} — ${hint}]${msg:+ · ${msg}}" + fail "ListBuckets GAGAL [HTTP ${st} — $(err_hint "${st}" "${code}" "${msg}")]${msg:+ · ${msg}}" else fail "ListBuckets tak menghasilkan keluaran yang diharapkan" fi @@ -246,9 +263,7 @@ elif [[ "${o5}" == ERR\|* ]]; then fail "bucket '${BUCKET}' TIDAK ADA [HTTP 404 — ${msg:-NoSuchBucket}]" info "Buat bucket di sisi pemilik/MinIO (bootstrap step 2 / config/minio/buckets.sh)." else - hint="cek endpoint/kredensial" - [[ "${st}" == "0" ]] && hint="tidak terjangkau (koneksi/DNS/TLS) — self-signed? set S3_INSECURE=1" - fail "baca bucket '${BUCKET}' GAGAL [HTTP ${st} — ${hint}]${msg:+ · ${msg}}" + fail "baca bucket '${BUCKET}' GAGAL [HTTP ${st} — $(err_hint "${st}" "${code}" "${msg}")]${msg:+ · ${msg}}" fi else fail "baca bucket tak menghasilkan keluaran yang diharapkan"