MYPRO / README.md
DD8777's picture
Update README.md YAML header to sdk: gradio with app_file: app.py for ZeroGPU compatibility
04bdd3f
|
Raw
History Blame Contribute Delete
12.5 kB

A newer version of the Gradio SDK is available: 6.25.0

Upgrade
metadata
title: MYPRO
emoji: 
colorFrom: blue
colorTo: indigo
sdk: gradio
sdk_version: 4.44.0
app_file: app.py
pinned: false

מעקף פרוקסי 2.0 (Etrog Bypass Proxy)

Reverse proxy מבוזר: Cloudflare Worker + Service Worker בדפדפן, לעקיפת סינון יתר (SNI/DPI/DNS) לצריכת תוכן חוקי (מנוי פעיל).

כתובת פרוסה

https://etrog-bypass-proxy.miriklain616.workers.dev

נתיב תפקיד
/ דף בית + ניווט
/ytp?v=VIDEO_ID נגן YouTube יציב (מומלץ)
/websearch?q=…&t=web|images|videos|news&p=N חיפוש נייטיב: רשת / תמונות / וידאו / חדשות
/api/websearch?q=…&t=…&p=N אותן תוצאות כ-JSON
/x/p?d=<token> פרוקסי תמונות כללי (אטום ב-XOR כשה-SW פעיל)
/cdn/<token> פרוקסי מוצפן (XOR) לכתובת יעד
/api/m?v=…&i=18 זרם וידאו YouTube (same-isolate)
/sw.js Service Worker
/import-cookies ייבוא עוגיות (YouTube / אתרים אחרים)
/api/health בדיקת חיים

חיפוש — למה אין "אני לא רובוט"

הכלל היחיד: המשתמש לעולם לא מגיע לדף של מנוע חיפוש זר. כל תוצאה נאספת ב-Worker ומוצגת בדף שלנו, ולכן אין CAPTCHA, אין באנר הסכמה ואין SPA שנשבר דרך הפרוקסי. Google / Brave / Mojeek / Startpage / SearX מציגים אתגר ל-IP של דאטה-סנטר — ולכן אינם בשימוש כלל, וגם הוסרו מהקיצורים בדף הבית.

לשונית מקור ראשי גיבויים
רשת Bing (עמוד 1) Yahoo (עמודים 2+ — רק לו יש דפדוף אמין), DuckDuckGo
תמונות Bing (לטינית) / DuckDuckGo (עברית ושאר כתבים) Wikimedia Commons
וידאו YouTube InnerTube → נגן /ytp הפנימי Bing Videos
חדשות Bing News RSS

שתי מלכודות שהקוד מטפל בהן:

  1. דפדוף של Bing מדומה. &first= מתעלם ומחזיר שוב את עמוד 1, ולכן עמודים 2+ מגיעים מ-Yahoo (&b=), שבו הדפדוף אמיתי.
  2. Bing "חוטף" שאילתות שאינן לטיניות. הוא מחזיר דף עם כותרת נכונה (ירושלים - חיפוש תמונות) אבל תוצאות שאינן קשורות בכלל — בלי שום קוד שגיאה. resultsLookRelevant() פוסל סט כזה וממשיך למנוע הבא; אם כולם נכשלים מוצג "לא נמצאו תוצאות" ולא זבל. הבדיקה חלה רק על מנועים שנגרדים מ-HTML — לא על API מובנה (Commons/RSS/InnerTube), שם הכיתובים לגיטימית בשפה אחרת.

תמונות עוברות דרך /x/p: ה-Worker מאמת magic-bytes, וה-Service Worker מוסיף X-Etrog-SW כדי לקבל אותן אטומות (XOR) — כך הפילטר לא מזהה JPEG ולא מטשטש. בלי SW הן מוגשות רגילות, כך שגם טעינה ראשונה עובדת.

איך עוקפים את הסינון (ומה נכשל קודם)

הפילטר (Rimon/Etrog) מסווג לפי גוף התשובה, לא לפי הכתובת. הוא עושה MITM על החיבור לוורקר, קורא את ה-HTML, ומחליף אותו בדף חסימה — מזוהה לפי rimon: RWC_BLOCK + server: lighttpd. לכן ynet ו-mako נחסמו, למרות שהוורקר החזיר אותם תקין.

התשובה: כל מה שניתן לסיווג נשלח אטום (XOR). הפילטר רואה בייטים חסרי-משמעות, ה-Service Worker מפענח לפני שהדפדפן רואה.

סוג אטום? למה
מסמך HTML (ניווט + iframe) זה מה שהפילטר מסווג
XHR/JSON אתרי חדשות מגישים את הכתבה כ-JSON
תמונות אחרת הפילטר מטשטש אותן
JS אטימה שברה מודולים של YouTube (SyntaxError)
CSS לא מסווג, וסיכון מיותר
פונטים בקשה שתחמוק מה-SW תקבל בייטים אטומים ו-OTS יפסול
מדיה / Range שובר ניגון פרוגרסיבי

המלכודת שהייתה: ה-Service Worker ויתר לגמרי על ניווטים (if (e.request.mode === 'navigate') return;), ולכן המסמך הראשי — בדיוק מה שנחסם — עבר בטקסט גלוי. בנוסף, ענף ה-HTML בוורקר החזיר תשובה לפני שהגיע לקוד האטימה, כך ש- X-Proxy-Obfuscate פשוט לא נלקח בחשבון עבור HTML. שני החצאים תוקנו.

אחרי ריווייט, כל משאבי המשנה של דף הם כתובות /cdn/ באותו origin — ולכן הענף ה-same-origin ב-SW (ולא זה של cross-origin) הוא שקובע מה נשלח אטום. הוא אטם רק תמונות.

ניווט בין דפים (הבאג של "הדף הראשי נטען אבל אי אפשר להתקדם")

רוב הקישורים עוברים ריווייט ל-/cdn/<token> ולכן הם חד-משמעיים. אבל כתובת "עירומה" — ניתוב SPA, קישור שנבנה ב-JS, או רענון של אחד מהם — מגיעה בלי יעד משלה, והוורקר חייב להסיק לאיזה אתר היא שייכת. שני מקורות המידע לכך היו שבורים:

  1. __proxy_target נדרס על ידי כל תשובת HTML — כולל <iframe> ממקור אחר או XHR שמחזיר HTML. מספיק ווידג'ט/פרסומת שמתארחת על S3 או CDN, והעוגיה של כל הסשן מצביעה עליו. הכתובת העירומה הבאה נפתרה ל-<bucket>/path, ו-S3 החזיר <Code>AccessDenied</Code>. תוקן: רק ניווט של מסמך ראשי מזיז את __proxy_target. iframe ו-XHR — לעולם לא.
  2. referrer-policy: no-referrer ביטל את הפתרון לפי Referer, שהוא דווקא המדויק, והשאיר את העוגיה (הניתנת לזיהום) כאות היחיד. תוקן: same-origin — כל בקשת משנה מפורקסטת היא same-origin ולכן שומרת Referer שימושי, ולאתרי יעד לא נשלח כלום. (הוורקר ממילא דורס את ה-Referer שיוצא החוצה לכתובת של אתר היעד עצמו.)

בנוסף, טעינת דף בכתובת עירומה מקבלת עכשיו 302 לכתובת הקנונית /cdn/<token>, כך שרענון, סימנייה או Back כבר לא תלויים במצב סשן שצד שלישי יכול להזיז.

ארכיטקטורה

  1. Service Worker מיירט Fetch/XHR/Media, מצפין כתובות (XOR + base64url, מפתח antigravity) ושולח ל-Worker.
  2. Cloudflare Worker מפענח, מביא מהיעד, משכתב HTML/M3U8/JSON, מחזיר תשובה (לעיתים מוצפנת).
  3. YouTube: נתיבי /watch מנותבים ל-/ytp; הזרם מגיע מ-/api/m באותו isolate של ה-Worker (מונע 403 IP mismatch).
  4. מדיה (Scania וכו'): זיהוי isMedia מדלג על HTMLRewriter כדי לא להשחית מקטעים בינאריים שמוסווים כ-text/html.

פריסה

# Windows PowerShell
$env:CLOUDFLARE_API_TOKEN="your_token"
npx wrangler deploy

או: npm run deploy אחרי npm install.

אבטחה

  • אל תשימו API Token בקוד או ב-git. השתמשו במשתנה סביבה CLOUDFLARE_API_TOKEN.
  • אם הטוקן דלף — בטלו אותו ב-Cloudflare Dashboard וצרו חדש.

Secrets מומלצים (Cloudflare → Worker → Settings → Variables/Secrets)

הקוד קורא קודם מ-env ונופל לברירת-מחדל רק אם לא הוגדר. הגדירו כ-Secret (לא Plaintext):

Secret תפקיד ברירת מחדל אם לא מוגדר
GATE_PASSWORD סיסמת השער הערך המוטמע (מומלץ לדרוס)
GATE_SECRET מפתח חתימת טוקן השער. שינוי שלו מנתק מיד את כל הסשנים (רוטציה) מפתח מוטמע — מומלץ לדרוס
NACHOTOY_SID סשן ה-VIP של Nachotoy (connect.sid בלבד, בלי השם) ריק → האתר פשוט לא מחובר-אוטומטית
# דוגמה (PowerShell)
$env:CLOUDFLARE_API_TOKEN="…"
npx wrangler secret put GATE_SECRET
npx wrangler secret put GATE_PASSWORD
npx wrangler secret put NACHOTOY_SID
  • טוקן השער אינו עוד ערך קבוע: הוא בפורמט v2.<תפוגה>.<חתימה>, פג אחרי 30 יום, וניתן לביטול מיידי ע"י שינוי GATE_SECRET.
  • connect.sid של Nachotoy הוסר מהקוד. הסשן הישן דלף ל-git history — החליפו אותו (התנתקו והתחברו מחדש ב-Nachotoy כדי לפסול את הישן) והכניסו את החדש כ-Secret‏ NACHOTOY_SID.
  • הגנת SSRF: נתיב /cdn/ חוסם כתובות פנימיות (loopback / RFC1918 / link-local / 169.254.169.254). ה-relay חוסם גם הוא כתובות-IP פנימיות בנוסף ל-allowlist של Google.

למה /ytp ולא YouTube עצמו

נבדק אמפירית (2026-07-26):

מאיפה youtube.com/watch תוצאה
Cloudflare (הוורקר) דף /sorry/ — CAPTCHA הוורקר נופל ל-makeSorryResponse/ytp
IP ביתי (relay) 938KB, playabilityStatus: OK, כתובות url= גלויות תקין לחלוטין
InnerTube API מ-Cloudflare ANDROID+IOS, 12 פורמטים עובד — וזה מה ש-/ytp משתמש בו

כלומר: דף ה-HTML של YouTube חסום ל-IP של דאטה-סנטר, אבל ה-API לא. /ytp מנצל בדיוק את הפער הזה, ולכן המדיה זורמת דרך Cloudflare (מהיר) ולא דרך הבית.

להצגה ביוטיוב עצמו צריך: להביא את ה-HTML דרך ה-relay (≈1MB לכל טעינת דף על החיבור הביתי), ואז להחליף את streamingData בתשובת /youtubei/v1/player בכתובות שהוורקר פתר בעצמו — אחרת כתובות googlevideo יהיו חתומות ל-IP הביתי בעוד הבייטים נמשכים מ-Cloudflare, ויחזור 403. התשתית לכך קיימת חלקית (rewritePlayerApiJson). ?yt_ui=1 הוא פתח המילוט הקיים לניסיון.

ניגון: למה 502 על /x/s/…bin

כתובות googlevideo חתומות ל-IP שפתר אותן. פורמט שנפתר בוורקר חתום ל-Cloudflare וחייב להישלף מ-Cloudflare; פורמט שנפתר דרך ה-relay חתום ל-IP הביתי וחייב לחזור דרכו.

הבאג: tryFetchMedia לקח את ה-relay בלעדית בכל פעם שהוא מוגדר, והחזיר null ברגע שהוא נכשל — בלי לנסות אף פעם את הנתיב הישיר. כשהמנהרה נופלת, הניגון מת לגמרי, למרות שהכתובות חתומות ל-Cloudflare וניתנות לשליפה ישירה (רואים את זה ב-ip=172.70.x שבתוך כתובת ה-videoplayback). התוצאה: "שגיאה בניגון" + מאות 502.

עכשיו שני הנתיבים נוסים, לפי הסדר שממנו הכתובות באמת הגיעו (pack.via).

בנוסף, לולאת הפורמטים בלעה חריגות (catch { /* next */ }), כך ש-502 היה עיוור לחלוטין. גוף השגיאה כולל עכשיו dbg[] עם ניסיון-אחר-ניסיון (סטטוס, content-type, שגיאה) — אם ניגון נכשל שוב, זה מה שצריך להעתיק.

פתרון בעיות YouTube

  1. פתחו /ytp (לא את ממשק YouTube המלא — לא יציב דרך CF).
  2. אם יש 502 / no format: /import-cookies עם עוגיות מחשבון מחובר (כולל SAPISID).
  3. כתובות googlevideo חתומות ל-IP של ה-Worker — אל תעבירו X-Forwarded-For.