מי באמת הפיל את רכבת ישראל
עונה 2 · פרק 56 · 00:00 ·
אין לי את הלוגים של רכבת ישראל או התחקירים שהובילו לקריסה, לכאורה, אבל יש משהו אחר - כל היסטוריית ה-Git של בטר רייל, שמתארת כל שינוי, מי עשה אותו ולמה. אז בניתי ממנו ציר זמן.
19 למאי 2026. לפי רכבת ישראל, מנוע החיפוש ותכנון הנסיעה שלה כשל שלוש פעמים ברצף. לא בגלל תקלה פנימית, אלא עומסי תעבורה חריגים ושימושים חיצוניים לא מורשים. בין השימושים האלה היא מציינת גם אפליקציה קטנה, חינמית ובקוד פתוח בשם Better Rail.
פחות משלושה חודשים אחר כך, מגיע מכתב התראה, עם ניסוח שכבר לא נשמע כמו שיחה בין צוותי פיתוח. רכבת ישראל טוענת לשימוש מסחרי בלתי מורשה, הפרת תנאי שימוש, גזל סוד מסחרי, חדירה לחומר מחשב, שיבוש פעולת מחשב והפעלת כלי תוכנה אוטומטיים. היא דורשת להפסיק כל גישה למערכות, למחוק את המידע, להסיר את האפליקציה מהחנויות ולמסור פירוט של הכלים, הממשקים, התדירות והרווחים. תוך 7 ימים. והנזק? לפי המכתב, מאות אלפי שקלים לפחות.
בטר רייל משיבה: אין פרסומות, אין מוצר בתשלום, אין רווחים, אין פריצה, ויש בערך אלף משתמשים ביום מול מאות אלפים באפליקציה הרשמית של הרכבת. היא דורשת לראות את התחקירים ואת נתוני התעבורה שמקשרים אותה לקריסות, ומציתה גל תמיכה ברשתות החברתיות.
מי צודק? אין לי מושג. אין לי את הלוגים של רכבת ישראל, של ספק הענן שלה או את התחקירים הפנימיים. בלי החומרים האלה קשה להוכיח שבטר רייל הפילה דבר. אבל יש לנו משהו אחר: חמש שנים של היסטוריית Git פתוחה לציבור, מעין ספר מבצעים של פרוייקט בטר רייל שמתאר כל שינוי. מי עשה את זה, מה, ולמה. וב-Git, בניגוד למכתב שהופץ בתקשורת, רואים את הכל.
אני כאמור לא הולך להכריע מי צודק משפטית, רק לבנות מספר המבצעים הזה timeline ולהסתכל על המערכת מבחוץ.
1 באפריל 2021. בטר רייל דוחפת לראשונה קוד ריאקט נייטיב - אפליקציית קיצור דרך לאייפון ואנדרויד, כזו שמרגישה נייטיב אבל נבנית עם טכנולוגיות web. בחירה הגיונית ותמימה, אבל מתאימה לרוח של 2021. החלטה ראשונה שאינה תמימה היא הקומיט ב-9 לאפריל 2021. המשתמש בוחר תחנת מוצא, יעד ושעה והאפליקציה קוראת ל-API שבו השתמש אתר רכבת ישראל.
אני אעצור כאן לטובת מי שלא מתכנת. קודם כל ברוכים הבאים. API או Application Programming Interface היא הדרך של צדדים לתקשר ביניהם בצורה תכנותית. צד אחד מגדיר את הפעולות שניתן לבצע אצלו, את מבנה הנתונים הנדרש בכל בקשה, ומבנה הנתונים הצפוי בכל תשובה. למשל - GetRoutes עבור תחנות 3400 ו-3700 (נניח: בית יהושוע ות"א מרכז) לתאריך ה-14/5. הפעולה הזו תחזיר לצד השני מערך של רכבות, זמני הגעה ונקודות עצירה, בצורה עקבית, ממוסמכת ומהירה שמתאימה לשימוש בקוד אחר.
אמרנו שני צדדים, הם לא צריכים להיות צדדים שונים. רכבת ישראל חושפת API לשירותים שלה עצמה, אפליקציית המובייל, אתר rail.co.il, אולי אפילו לשלטים האלקטרונים בתחנה. שרת ה-API של הרכבת הופך להיות מקור האמת, ומחזיק במידע קריטי לתכנון הנסיעה של 100 עד 250 אלף נוסעים ביום.
בטר רייל מצאה את ה-API הזה, שלרוב מוגן במפתח או לוגין, ושלחה את המשתמשים להשתמש בו תחת המעטפת שלה. בסיס רע למוצר שרוצה לחיות שנים, שכן בלי הסכמה ובלי נעילה, שום דבר לא מונע מהרכבת להחליף משהו בשרת ולשבור כל צד שמסתמך עליו.
ב-8 לאוקטובר 2021 בטר רייל מוסיפה תמיכה ב-Apple Watch.
ב-18 לדצמבר 2021 מתווסף ה-iOS Widget, אולי הפיצ׳ר האהוב עליי ביותר - דרך לראות את לוח הזמנים מבלי להיכנס לאפליקציה.
בשלב הזה, כל הצרכנים של בטר רייל ממשיכים לקרוא לשרת הרכבת ישירות, אבל עושים את זה במגבלות ברורות:
האפליקציה - קוראת לרכבת בכל חיפוש (אקטיבי) של משתמש ושומרת את התוצאה לשעתיים. היא לא מתשאלת כשהיא סגורה או ברקע.
השעון - מתמקד במסלולים מועדפים ומבקש זמנים בכל פעם שמישהו פוזל ל-Apple Watch, כל עוד לא עברה שעה וחצי.
והווידג׳ט - מבקש זמנים פעם ביום, לכל היום.
בשלהי 2021 מדובר על 5-15 בקשות יומיות למשתמש.
ספויילר - המספר הזה עומד לעלות. הרבה.
לקח לרכבת שנתיים להחליף API. במרץ 2023 היא עוברת שרת או ספק ענן. הכתובת הישנה נעלמת ובמקומה מגיע API חדש מאחורי Azure API Management. מעכשיו, כל בקשה צריך לכלול Subscription-Key. מפתח זיהוי או מנוי.
בטר רייל מסתגלת באותו יום, היא מחליפה את הקריאה הקודמת במשתנה RAIL_API_KEY ומבינה, זה עומד להיות ערך שיוחלף באופן תכוף, והמקום שלו - לא בקוד אלא במשתנה סביבה.
שוב נעצור אם זה מעניין מישהו. ה-Git כולל את כל ההיסטוריה, ומאוד קשה לנקות אותה. מפתחות לא שמים בקוד, שמים במשתני סביבה זמניים או כספת, בצורה שלא נגישה למי שבא לחטט בקוד (כמוני), או לטפל בקוד, כולל סוכני קוד.
זו נקודת מפנה עדינה. Better Rail עדיין לא פרצה חשבון ולא גנבה סיסמה פרטית. היא מצאה את המפתח הזה באתר הרכבת עצמו. אבל היא כבר לא דפדפן אנונימי. במשך יותר מ-3 שנים התעבורה שלה תיספר תחת מנוי שלא הונפק עבורה. הרכבת - עיוורת למי באמת הלקוח, ובטר רייל - היות ואין בנמצא תוכנית מפתחים, מתקשה לקבל מכסה משלה. שני הצדדים נכנסים למנהרה ארוכה וחשוכה.
ב-28 לאפריל 2023 בטר רייל מתחיל בהכנות לפיצ׳ר Live Activities של iOS. הכוונה טובה - לדחוף למכשיר עדכונים בזמן אמת על שינויי לו"ז. הביצוע לא טוב - היות ולרכבת ישראל אין שירות push, צריך למשוך, pull, את השינויים האלה. ומאיפה נמשוך? מה-API של הרכבת. בתקופה של 16 יום בטר רייל דוחפת שינויים לפיצ׳ר שיגדיל את הקריאות בסדר גודל.
עכשיו, כל פעם שעלית על רכבת, ובכל דקה משם, מתווספת קריאה לבדוק שינויים מול הרכבת, ואם הם קיימים הם נדחפים לבטר רייל כדי שהיא תוציא פוש שיעדכן את ה-Live Activity.
יש פה עוד שינוי, עדין. בטר רייל תוסיף שניה אקראית לכל קריאה כדי לא לגרום לפקק, אבל זו לא שניה אקראית לכל מחזור אלא לכל משתמש. נראה שבטר רייל ניסתה לרכך את העומס, או לפחות הייתה מודעת למשמעויות שלו.
ב-14 למאי 2023 היא מנסה להקטין את גודל הבקשה (אין טעם לבקש רכבות מלפני שעתיים), אבל מכפילה את מספר הקריאות - הפיצ׳ר של "התחלת נסיעה" קורא לרכבת במסלול נוסף, מקביל, ולא משתמש בקריאות שכבר בוצעו.
אנחנו כבר על 120 קריאות יומיות למשתמש בערך.
וכך בדיוק נבנות תקלות scale אמיתיות: לא באמצעות החלטה אחת גרועה, אלא צירוף של 5 קומיטים שאיש לא הכפיל זה בזו. אם יש 100 משתמשים פעילים, שתי בדיקות בדקה הן 200 חיפושים. אם יש אלף, אלה 2,000 ואם כל חיפוש נכשל ומנסה שוב, אז זה 6,000 או 100 קריאות לשניה.
ב-22 לאוגוסט 2023 יש כבר עדות ב-Git לכך שכשל בצד הרכבת משפיע על Better Rail. קומיט אחד מתקן crash בשרת שנגרם בזמן ש-API הרכבת קרס, קומיט אחר מקטין את מספר השאילתות המקביליות מ-20 ל-8. זה תיקון בריא ליציבות של Better Rail, אבל הוא מלמד שהמערכות כבר כרוכות זו בזו: השרת ברכבת משתעל, האפליקציה של בטר רייל קורסת, קמה מחדש ואז מסתערת כדי לשחזר את כל המשימות הפעילות.
ב-30 לאוגוסט 2023 נוספים שני תיקונים לספריית axios. הראשון - כל כישלון מקבל ניסיון נוסף. כן, גם אם הוא סטטוס 500 (שאומר "בעיה בשרת"), גם ב-429 (שהוא "אתה שולח יותר מדי") וגם ב-403 ("אינך מורשה"). השני - exponential backoff או המתנה מעריכית. אם בטר רייל נכשלה, אז הקריאה הבאה תגיע עוד 200 מילישניות ולא מיד, והבאות, עוד 400, 800 ו-1,600 מילישניות. אבל בעולם האמיתי, זו לא החלטה של בטר רייל, זו החלטה של הרכבת. כל API אחראי להחזיר Retry-After שמוסיף בעצמו backoff משמעותי וגם jitter, כדי שלא כל הלקוחות יחזרו באותה אלפית שניה.
בקוד של Better Rail לא הייתה כוונה לפגוע. הייתה הנחה שהמידע חשוב ולכן צריך לנסות שוב. אבל השרתים של הרכבת, ואני באמת לא יודע אם עלו להם מאות אלפי שקלים, לא מחייבים על כוונה, הם מחייבים על קריאות.
ב-10 ליולי 2025 היחסים מתערערים והופכים לתופסת בין חתול ועכבר. בטר רייל מוסיפה לשרת שלה PROXY_URL ומאפשרת בו חיבור לא מאובטח. ה-Proxy מאפשר לשרת שמתארח מחוץ לישראל לצאת דרך כתובת אחרת ולעבור מגבלה גאוגרפית. ביטול אימות TLS הוא כבר מחיר אבטחתי כבד - מהסוג שלוקחים ב-2 בלילה כי השירות הפסיק לעבוד.
ה-16 ליולי 2025 הוא עוד יום שלם של כיבוי שריפות. ה-rate limiter מוסר זמנית ונוסף נתיב בשם headers, כדי לבדוק אילו כתובות רואה השרת. זה לא מוכיח מי חסם את מי או מדוע, אבל זה מתאים לצוות שמנסה להבין כיצד התעבורה שלו מזוהה.
אגב גיט כולל גם commit messages או הערות של מפתחים, בעצם הדרך שלהם להסביר מה השתנה ולמה. מצחיק לקרוא חלק מההערות האלה, ולראות איך לחץ, מצב רוח או התרוממות מחלחלים אליהן.
ב-9 לאוגוסט 2025 הפרוקסי מוכן ובטר רייל מעבירה דרכו בקשות לרכבת. יום לאחר מכן מופיע בריפו של האפליקציה קומיט בלי הרבה מקום לדמיון: Bypass Israel Railways API restrictions. ב-16 לאוגוסט 2025 ההתנהגות עוברת אוטומציה - האפליקציה תפנה לרכבת ישירות, ואם היא מקבלת 403 היא תעבור ל-Proxy ותנסה שוב.
403 אינה בעיה זמנית. היא החלטה של הרכבת לפסול את הבקשה. אפשר לטעון שההחלטה פסולה, לא מידתית או לא ראויה לגוף ציבורי, אבל אי אפשר לטעון שבטר רייל לא שמעה אותה. היא שמעה אותה ובחרה להיכנס מהצד.
Better Rail השתמשה בזהות שלא הונפקה לה, עקפה מגבלה גאוגרפית, הפעילה fallback אחרי 403 וריכזה תעבורה דרך proxy עם קאשינג מוטל בספק. בוא נניח שהרכבת היא ספרייה ציבורית - הספרים מיועדים לציבור, אבל זה לא מעניק לי זכות להשתמש בכרטיס של הספרנית, להיכנס דרך החלון או להפעיל רובוט שמצלם מדפים פעם בדקה. מצד שני, אם הספרייה היא היחידה שמחזיקה מידע חיוני והיא מסרבת להנפיק כרטיסים לקוראים, יש לה חלק לא קטן ביצירת שוק החלונות.
ב-29 לספטמבר 2025 ה-endpoint הישן נחסם ב-Cloudflare, שמאבטח את שרת הרכבת. בתוך שעות Better Rail משנה את הקריאה לרכבת מ-GET ל-POST, תוך שהיא מבריחה פנימה methodName כדי להמשיך לשרת את המשתמשים.
ב-9 לאפריל 2026, בדיוק 40 יום לפני האירועים שרכבת ישראל תזכיר במכתב, בטר רייל מוסיפה עוד רענון למנגנון של React Query, אולי מכפיל העומס הגדול ביותר שנמצא בגיט, והוא מתואר עם אימוג׳י של באג. לא ברור כמה הוא ספציפית תרם לכשל הרכבת במאי, כי יש המון אימוג׳יס כאלה בריפו.
ב-1 ליוני 2026 אנחנו עדים לעיצומו של מרוץ החימוש. ה-WAF של קלאודפלייר חוסם בקשות ל-searchTrain והשרת של בטר רייל, יחד עם האפליקציה, עוברים ל-searchTrainForMobile. בטר רייל מעצבת payload מלאכותי שכולל user agent של iPhone Safari, רזולציית מסך, כתובת IP ומיקום מומצאים. זו עדיין בקשת HTTP רגילה, אבל היא מעוצבת כדי להידמות ללקוח שהמערכת מצפה לקבל.
ב-22 ליוני 2026 הרכבת יוצרת קשר רשמי. אין לי את כל התכתובת המקורית, ולכן לא ברור אם בטר רייל סולקה מיד או שניתן לה זמן חסד. מה שכן יש לי הוא Git. ב-27 ליוני 2026 נפתח PR מספר 28 בשרת ו-631 באפליקציה. בעוד ששני הצדדים מתדיינים על הטון בשיחה ההיא, הקוד מראה שחמישה ימים אחרי הפנייה התחיל מעבר מתואם וממשי אל מקורות מידע רשמיים במשרד התחבורה.
המעבר הזה מסביר מה היה אפשר לעשות מלכתחילה. GTFS או General Transit Feed Specification הוא אוסף קבצים סטטיים שמתאר תחנות, קווים, נסיעות ולוחות זמנים לא רק לרכבת, אלא לכלל אמצעי התחבורה. זו גישה חינמית שמקבלים לאחר מילוי טופס במשרד התחבורה.
בטר רייל מפשילה שרוול ומתחילה לעבוד. תוך כמה ימים היא טוענת את ה-Feed למסד נתונים משלה, פעם ביום, ומנטרת אירועים בזמן אמת בפרוטוקול SIRI. היא שומרת על מבנה המידע כדי לא לשבור אפליקציות ישנות ומצליחה להתגבר כמעט על כל החוסרים בזמן שיא. היא מכריזה שהתנתקה מרכבת ישראל בפוסט ברשת איקס.
ב-16 ליולי 2026 הפקקים חוזרים לשמפניה. בטר רייל מדווחת לרכבת על פערים משמעותיים במקורות הרשמיים. אין סימון רציפים או קרונות, אין עדכונים לעבודות שירות ותקלות, וזמני ההגעה - הלחם והחמאה של בטר רייל - פשוט שגויים.
הרכבת, מודעת לחוסרים, דרשה להשתמש בערוץ רשמי. אבל הערוץ הרשמי לא החזיק את כל מה שהלקוח צריך. המפתח הלא רשמי גילה את הפער כי הוא לקוח בעצמו, וכשתיאר אותו לרכבת, במקום להודות, במקום לתת לו bug bounty נתנו לו מכתב לפני תביעה.
ב-9 לאוגוסט 2026, אותו יום בו נשלח מכתב ההתראה, ה-Git מתעד את שני הצעדים האחרונים להתנתקות: הרציפים נלמדים מתצפיות SIRI במקום להימשך מרכבת ישראל, וה-proxy הישן יוצא מכלל שימוש. מאותו רגע, כל widget, כל קליינט, כל שעון ומכשיר טלפון, פונים לשרת Better Rail בלבד. אחרי 5 שנים של תלות, בטר רייל מנתקת את חבל הטבור.
זה לא קרב על כסף. Better Rail החינמית קיבלה בכל פעילותה בערך 2,000 שקלים. זה בערך 5 שעות עבודה של המתכנת הבכיר שלה, למשך 5 שנים, מיזם שעזר למאות ואלפים.
זה קרב על שקיפות, לפחות זה מה שבטר רייל מנסה לקדם, והיא עושה את זה כי להקטין את הסיפור על הפעילות. כאילו לא היה בה דבר מיוחד. אבל, הקוד כן עשה דברים מיוחדים, תיארתי, אילו. אפשר לטעון שכל תגובה הייתה פרגמטית לחסימות שפגעו במשתמשים, או שהרכבת לא סיפקה חלופה, אבל אי אפשר לכווץ את הטענה לכך שאלו "אותן בקשות שהמשתמשים היו שולחים ממילא". האפליקציה הרשמית אולי גם מרעננת ומנסה שוב, אבל Better Rail עשתה את זה נכון רק בקומיטים האחרונים, ורק כשהכריחו אותה.
הטיעון של רכבת ישראל חזק כשהוא מדבר על שרתים שנפלו, והוא נחלש כשהוא קופץ למונחים פליליים דרמטיים, ולדרישה למחוק מוצר שלם.
מה רכבת ישראל הייתה יכולה לעשות? לעבוד עם הממשלה כדי להנגיש את GTFS ו-SIRI במלואם, ועד שזה יעשה - להנפיק למפתחים גישה נפרדת עם quota ו-dashboard.
מה Better Rail הייתה יכולה לעשות? להעביר את כל הגישה לשרת מרכזי כבר ב-2023, לבצע deduplication ו-caching, להגדיר timeouts ו-concurrency נכונים, ולשמור telemtry שמראה בדיוק כמה תעבורה נשלחה, כדי שיהיה אפשר לטעון על קריסה במספרים ולא באמונה.
מה שני הצדדים יכולים לעשות יחד נשמע כמעט מביך: לפתוח ערוץ טכני. לגשר על הפערים בפגישה משולשת עם משרד התחבורה ולהמשיך לשרת משתמשים. במקום זה, כל צד ענה לשני בכלי היחיד שהוא הכיר. הרכבת שלחה 403, בטר רייל ענתה בפרוקסי. הרכבת שמה WAF, בטר רייל התחפשה לאייפון. זו לא היתה תקשורת, והיא התפוצצה בצורה הכי גרועה שיש לרכבת.
ועוד משהו ששני הצדדים יכלו לעשות, אנחנו חיים בתקופה מעולה שבה ניתן לנתח קוד ולשפר קוד מדי יום. להריץ את הריפו שלכם מדי פעם דרך קלוד ולשאול אותו, מה היית משפר - זה משהו שאפשר לעשות היום, ובכל יום, במיוחד שאתה פקוד על תשתיות לאומיות, וגם אם אתה בונה אפליקציה שמתפוצצת ממשתמשים.
ואם מעניין אתכם ללמוד עוד על תשתיות וסקייל, דווקא בעידן של וייב-קודינג, אז יש לי קורס בכתובת shipreal.dev
עד הפעם הבאה, תהיו טובים, ותמשיכו להיות סקרנים. יאללה ביי.