עוד תקלת רשת מוזרה

בהמשך לפוסט האחרון על בעיות רשת מוזרות, הנה עוד אחת.
אפליקציית ג'אווה שכתבנו עובדת טוב לרוב האנשים, אבל משום מה "נתקעת" בהתחברות לחלק מהאנשים.
בבדיקה, נראה שהאפליקציה מתחברת לשרת, מקבלת תשובה ממנו, אבל לא קוראת את התוכן של התשובה.
בבדיקה מעמיקה יותר, רואים שהאפליקציה ניגשת לשדה הContent-Length של התשובה, ומקבלת משם 1-, מה שמרמז על זה שאין בתגובת הHTTP שדה של Content-Length.
בדיקה קטנה עם WireShark (לשעבר Ethereal) מראה את זה:

[code]
HTTP/1.1 200 OK
Date: Thu, 31 Jan 2008 13:21:24 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Set-Cookie: ASP.NET_SessionId=j2hx2qvprzec3u55htsykh45; path=/; HttpOnly
Cache-Control: private
Content-Type: text/html
Content-Length: 20877
[/code]

(המשך התגובה נחתך מחוסר עניין).

אז נראה שהכל בסדר, יש Content-Length בתגובה.
ובכל זאת, אפליקציית הJava מקבלת 1-, ובדיבוג מעמיק אין רמז לContent-Length באובייקט שמייצג את תגובת הHTTP.
אז מה קורה פה?

הצעד הבא הוא לבדוק TCP נקי, בלי טובות של Java בפירסור התגובה.
תוכנית קטנה שמתחברת בTCP לשרת הHTTP, שולחת את הבקשה ומדפיסה את התוצאה מהשרת הפיקה את הפלט הזה:

[code]
HTTP/1.1 200 OK
Transfer-Encoding: chunked
Date: Thu, 31 Jan 2008 13:21:24 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Set-Cookie: ASP.NET_SessionId=j2hx2qvprzec3u55htsykh45; path=/; HttpOnly
Cache-Control: private
Content-Type: text/html
————–: —–
[/code]

יש פה כמה דברים שצריך לשים אליהם לב:
1. פתאום יש לנו בתשובה Transfer-Encoding: chunked.
2. מה זה איפה שקודם היה לנו Content-Length? ————–: —– ?? איזה וודו שחור פועל פה?

יש לציין שבזמן שאני מקבל את הנתונים האלו בתוכנית, אני מקבל נתונים זהים למה שראיתי קודם WireShark, כלומר – המחשב מקבל את הנתונים בצורה תקינה, אבל התוכנית מקבלת אותם אחרי טיפול.

כדי לנטרל אפשרות שJava התחלקה על השכל, ניסיתי (בעזרתו של חבר מהעבודה) להריץ תוכנית שעושה את אותו דבר בדיוק, רק שכתובה בC#.
לא במפתיע, התוצאה זהה: אין Content-Length, במקום זה יש שורת מינוסים.
מסקנה, Java לא אשמה הפעם.

אז מה נשאר?
מי משחק בתעבורת הרשת במחשב? אולי זה ווירוס, ואולי זה אנטי וירוס; בכל מקרה מדובר בתוכנה נאלחת.
לא במפתיע, האשם הוא הSymantec Client Firewall, שסורק בזמן אמת את תעבודת הHTTP, מחרבש אותה קלות, ומעביר את הזבל לתוכניות התמימות.
ברגע שנטרלתי את הסריקה שלו את פורט 80, הכל הסתדר.

יש לי משהו לומר למהנדסים של סימנטק:
אתם אינוולידים, מי נתן לכם את הזכות לשבש את התעבורה?
תסרקו, זה בסדר, אבל אין שום הצדקה שבעולם שהתוכניות שקוראות מהרשת יחשפו לשינויים שתרמתם.
אם הייתם עובדים אצלי הייתי משבש לכם את המשכורת.

אם הייתי כותב ווירוסים, הייתי משתמש במידע הזה בכיף כדי לזהות שהמחשב מריץ את הFirewall של סימנטק, שמשאיר עקבות כמו חזיר בחנות בורקסים.

ייעול הכנסת נתונים מנורמלים לבסיס הנתונים בFireStats

במסגרת מקצה אופטימיזציות לFireStats מימשתי מנגנון נוסף לקליטת כניסות.
המנגנון הרגיל בו כולם משתמשים היום בודק שהכניסה לא צריכה להיות מסוננת (כניסה של רובוט ידוע או IP מסונן למשל), ומכניס את הנתונים בצורה מנורמלת.
נירמול בסיס נתונים נועד למנוע כפילויות, מה שעוזר במניעת אנומליות ובחיסכון במקום. בFireStats הנרמול מתבטא בכך שכל כתובת נשמרת פעם אחת בטבלאת הURLים, כל UserAgent בטבלאת הUserAgents וכדומה. כאשר מכניסים את הנתון העיקרי של כל הכניסה, משתמשים במזהה של כל נתון מנורמל.
המשמעות של זה בזמן הכנסת הנתונים היא כזו:
הגיעה כניסה עם כתובת מסויימת, מפנה מסויים ודפדפן (UserAgent) מסויים. לכל אחד מהנתונים האלו מבצעים פחות או יותר את סדרת הפעולות הבאה:
הכנס לטבלא הרלוונטית עם INSERT IGNORE, מה שמונע שגיאה במקרה שהנתון כבר נמצא שם (הטבלאות מוגדרות לא לקבל רשומות כפולות).
בדוק מה המזהה של הנתון שהכנסנו (אם הוא נכנס, אז זה יהיה מזהה חדש, אם לא זה יהיה המזהה שנבחר בפעם הראשונה שהכנסנו את הנתון לטבלא).
לבסוף, הכנס שורה לטבלאת הכניסות תוך שימוש במזהים שמצאנו בצעדים הקודמים.
זה קצת יותר מורכב מזה כי גם צריך לזהות ולסנן כניסות מסויימות כאמור.

כל התהליך הוא איטי למדי.
יצרתי קובץ CSV עם 100,000 כניסות (מfirestats.cc) והשתמשתי בו למדידת הביצועים:
בשיטה של הכנסה מנורמלת של כל כניסה, הקצב מתחיל די לא רע עם 80 כניסות לשניה, אבל ככל שבסיס הנתונים מתמלא הוא יורד עד שמתייצב על 7-8 כניסות לשניה.
למרות שקצב כזה בהחלט מספיק לכל בלוג מצוי, הוא ממש לא מספק לאתרים רציניים יותר או לבלוגיות עתירות בלוגים.

כשהוספתי תמיכה בWPMU בFireStats 1.4, חזיתי (חודשים לפני שביצעתי את המדידות) שקצב הכניסות יכול להיות בעיה בבלוגיות והוספתי שיטה חדשה לקליטת נתונים.
במקום לקלוט את הנתונים בצורה מנורמלת, הנתונים נקלטים לטבלאת כניסות ממתינות בצורה לא מנורמלת עם INSERT DELAYED. המשמעות של הDELAYED היא שבסיס הנתונים מכניס את הנתונים בזמנו הפנוי, ולא מחזיק את הקורא עד שהנתון הוכנס ממש.
עדיין צריך לנרמל את הנתונים, ולכל כתבתי סקריפט PHP פשוט שעובר על הכניסות הלא מנורמלות בטבלא אחת אחת, ולכל אחת קורא לפונקציה הרגילה שקולטת נתונים ומנרמלת אותם, ולבסוף מוחק את הכניסה מטבלאת הכניסות הממתינות. (מנהל המערכת אחראי לדאוג שהסריפט ירוץ בפרקי זמן סבירים, למשל באמצעות cron).
אני שומע אתכם צועקים: כן, אבל זה יהיה איטי לפחות כמו קודם, אם לא יותר!
זה נכון, אבל לפחות זה מאפשר לתזמן את העיבוד של הכניסות לזמנים פחות עמוסים כמו הלילה.
חיסרון נוסף הוא שהמשתמשים כבר לא מקבלים את הנתונים בזמן אמת, אלא נתונים שנכונים נכון לזמן העיבוד האחרון של הכניסות בטבלאת הממתינים.

אחרי שמדדתי את הזמן שדרוש כדי להכניס 100,000 כניסות בשיטה הרגילה, כמובן שמדדתי את הזמן שדרוש בשיטה המעוכבת, שנועדה לשפר ביצועים.
מסתבר שבשיטה המעוכבת, FireStats קולט בסביבות ה1000 כניסות לשניה, אבל המילכוד הוא שהנתונים עדיין דורשים עיבוד כדי שיהיו שימושיים, והעיבוד יקר בדיוק כמו הטיפול הרגיל.

הצעד הבא הוא כמובן לשפר את הביצועים של העיבוד הנ"ל.
כבר מהרגע הראשון שכתבתי אותו, היה לי ברור שדרושה פה אופטימיזציה רצינית, והיה לי גם ברור שהיא תהיה מסובכת.
האופטימיזציה מתבססת על התובנה הבאה:
בתוך קבוצת כניסות שנקלטו בפרק זמן מסויים, יהיו חזרות רבות מאוד של כתובות, מפנים ודפדפנים.
מה אם במקום לטפל בהם אחד אחד, נטפל בהם בקבוצות? נניח 1000 כניסות בכל קבוצה?
במקום 1000 כתובות ו1000 מפנים, יהיו לנו משהו כמו 300 כתובות (שכוללים מפנים).
במקום משהו כמו 1000 דפדפנים יהיו לנו משהו כמו 50 או 100 דפדפנים.
עכשיו נצטרך להכניס את כל מה שחדש לבסיס הנתונים, לחלץ את המזהים שלהם, ולבסוף להכניס את הכניסות עצמן תוך שאנחנו משתמשים במזהים מקודם, רק שהפעם נכניס 1000 כניסות במכה במקום כניסה אחת.
המשמעות של זה היא בעצם לממש את הפונקציה שמכניסה כניסה בודדת – אבל לרוחב, כך שתהיה ברוחב של k כניסות (קבוע כלשהו).
המימוש של זה מורכב, ולמעשה לקח יותר מפי עשר שורות קוד מהמימוש התמים הקודם, אבל הביצועים סוכר:
מעיבוד של 8 כניסות בשניה, עליתי לעיבוד של 600 כניסות לשניה.
שיפור של פי 75!

עכשיו נשאר רק לבדוק נכונות.
אם אני לוקח חבילת כניסות נתונה, ומכניס אותה השיטה המיידית אך האיטית, או מכניס אותה בשיטה המעוכבת אך המהירה התוצאה בבסיס הנתונים צריכה להיות זהה.
לא דומה, זהה.
בהתחלה השתמשתי בmysqldump (תוכנית שמגיעה עם mysql כדי לגבות את בסיס הנתונים) כדי לשמור שני קבצים, מתוך כוונה להשוות אותם.
מסתבר שזה לא היה רעיון כל כך מוצלח, כי היא הפיקה שורות ארוכות מאוד מאוד, שגרמו לרוב תוכנות ההשוואה שניסיתי להתבלבל או פשוט להיות לא שימושיות.
הצלחתי לדעת שיש בעיות, אבל לא הצלחתי לזהות אותן.

אחרי חיפוש קצר מצאתי את phpsqldiff, תוכנת קוד פתוח שמאפשרת השוואה של טבלאות.
phpmysqldiff מסוגלת לומר בדיוק מה נוסף, מה ירד ומה השתנה בין שתי טבלאות, ובעזרתה מצאתי בדיוק מה שגוי ומשם הדרך לפתרון היא די קצרה.

אני שוקל ברצינות להפוך את שיטת קליטת הכניסות הזו לשיטה היחידה, אבל בשביל שזה יקרה היא תצטרך להיות יותר ידידותית למשתמש הפשוט:
למשל אם תהליך העיבוד יתבצע אוטומטית פעם ב10 דקות, ואולי אפילו בכל פעם שמנהל האתר בודק את הסטטיסטיקות.
מימוש כזה יגרום לעסק להיות שקוף, תוך הורדה משמעותית מהעומס על השרת.

זה עדיין לא הסוף של מקצה שיפור הביצועים: אני עדיין צריך לשפר את הביצועים של השאילתות, אבל זה בהחלט צעד חשוב בכיוון.

012 וTorrentLeech

012 סמייל קווי זהב (או איך שלא קוראים להם היום), שנולדו מהרכישה של 012 על ידי אינטרנט זהב נחשדים בזיוף של תעבורה אינטרנט שנועדה לגרום להחרמה של משתמשי TorrentLeech.
בעבר היו לי לא מעט בעיות מהירות עם אינטרנט זהב שהסתיימו כשהתנתקתי מהם.
כבר בעבר חשדתי שאינטרנט זהב משתמשת בטכניקות מסויימות כדי לפגוע בקצב ההעלאה של משתמשים, ואם הטענות של מנהלי TorrentLeech נכונות, אז 012 סמייל קווי זהב (או איך שלא קוראים להם היום) עברו את הגבול הדק שבין ניהול משאבים על גבול הלגיטימי לזיוף נתונים כדי להפיק רווחים, פעולה פלילית ללא ספק.
יש דמיון עקרוני רב בין המקרה של Comcast, שזייפו חבילות RST שנועדו לגרום לצד השני לחשוב שהצד המחובר סגר את החיבור לבין מה שסמייל קווי זהב (או איך שלא קוראים להם היום) נחשדים בו.
הייתי אומר שהפתרון של Comcast יותר מתוחכם טכנולוגית ויותר קשה לזיהוי ושהפתרון של 012 (או איך בלה בלה) יותר גס טכנולוגית אבל יותר נבזי בהרבה.
הסיבה היא שהפתרון של 012 (בלה) נועד לגרום לשרתי TorrentLeech לחשוד שהמשתמש מנסה לגרום לאתר לחשוב שהוא העלה כמויות נתונים גדולות ולא סבירות במטרה לגרום להחרמתו מהאתר.
זו מתקפה מאוד ספציפית על משתמשי TorrentLeech, ואם זה אכן קרה, אני מצפה שכל משתמשי TorrentLeech שמחוברים דרך 012 (בלה) יתנתקו ויעברו לספק שלא חוסם/מגביל/מרמה/משקר/עובר על החוק (עדיין?) כמו בזק-בין-לאומי.

הערה:
הטענה של TorrentLeech לא הוכחה עדיין.

הנה ההודעה המקורית של TorrentLeech:

2008-01-24 – ISRAEL USERS

Unfortunately it seems, that a few Israeli ISPs, are intensionally altering the announces to our tracker of their clients, announcing to our tracker false stats (over 8.000.000 TB of upload and download) in order for these users to be probably banned (and save some bandwidth). We made a script to automatically detect this false announce, and reset the user's account (reset uploaded/downloaded). Although this is NOT a fix, only a temporary solution, we cannot do anything more from our part, since this is not a problem of our tracker. We know that reseting these accounts is not pleasant, but the other alternatives were to ban these accounts or to ban all the Israel Golden Lines ip block (which unfortunately seems very possible in the future, since our tracker gets hammered because of the problem above)
Seems most of the users having this problem use the ISP-> GOLDENLINES

מילואיכס

אני יוצא למילואים לשבוע, אז כנראה שיהיה פה שקט בשבוע הקרוב.

עברית או אנגלית?

הבלוג הזה טכני ברובו, ויקרא על ידי יותר אנשים אם הוא יהיה כתוב באנגלית.
השאלה היא מה דעתכם בנדון, קוראי היקרים מפז.
(תסלחו לי על העימוד של הסקר, יכול להיות שהוא יהיה לא רלוונטי בקרוב 🙂 )

אם הבלוג יעבור להיות בלוג באנגלית, תמשיכ/י לקרוא?

View Results

Loading ... Loading ...

חור אבטחה מובנה בUPNP

UPNP היא טכנולוגיה שנועדה לפשט את התהליך של הוספת שרתים ונקודות קצה לרשת. אחד השימושים הפופולריים של UPNP הוא לאפשר קידום פורטים אוטומטי.
נניח שיש לכם רשת מקומית קטנה מאחורי NAT (תצורה מאוד נפוצה בימינו, כמעט כל מחשב שמחובר לאינטרנט דרך נתב מהווה בעצם רשת מקומית כזו), ותוכנת שיתוף באחד המחשבים רוצה לאפשר התחברות אליה מבחוץ.
לפני UPNP, התוכנה לא תוכל לעשות את זה בעצמה, ומנהל המערכת (או המשתמש התמים שקנה את הנתב) יצטרך להגדיר את הנתב "ולפתוח פורטים", או ליתר דיוק – לקדם פורטים מסויימים אל המכונה הספציפית.
היום רוב הנתבים תומכים בUPNP, מה שמאפשר לתוכנת השיתוף למצוא את הנתב, לגלות שהוא תומך בקידום פורטים, ולבקש ממנו בדרכי נועם לקדם למחשב עליו היא רצה חבילות מידע שמגיעות לפורטים מסויימים.
מאוד נוח, הכל פשוט עובד.
הבעיה היא שUPNP לא כולל אימות (כי אחרת המשתמש היה צריך להגדיר שם משתמש וסיסמא בנתב לצרכים האלו, ולתת לתוכנת השיתוף את שם המשתמש והסיסמא, דבר לא נוח בעליל!) ולמעשה מאפשר לכל תוכנה שרצה של מחשב בתוך הרשת לבקש קידום פורטים בלי בקרה מיוחדת ובצורה שקופה ונסתרת מהמשתמש.

הבעיה מתחילה כהמשתמש מריץ תוכנה בלי להבין אפילו שזה מה שהוא עושה.
למשל, אתם גולשים לתומכם באינטרנט, בטוחים שהתוכנה היחידה שאתם מפעילים היא הדפדפן, אתם נכנסים לדף כלשהו שמציג אנימציית פלאש.
הופ, הרצתם תוכנה חיצונית.
לא הפלאש, אלא האנימציה עצמה.
בצורה דומה הפעלה של ישומון ג'אווה היא בעצם הפעלה של תוכנה חיצונית בתוך הרשת שלהם. במקרה של ג'אווה המצב עוד יחסית בסדר כי רק ישומונים חתומים יכולים להתחבר לשרתים אחרים מזה שהם ירדו ממנו (ישומים חתומים הם נדירים למדי כי כדי לחתום יש לרכוש חתימה מסמכות שורש כמו Verisign או Thawte, מה שעולה כמה מאות דולרים לשנה ויאפשר זיהוי של מקור הקוד).
לעניין, פלאש מאפשר התחברות לנתב ובקשה לקידום פורטים, בנוסף UPNP מאפשר בנתבים מסויימים לשנות את שרת הDNS של הנתב, מה שיכול לאפשר תכמון של המשתמש ברמות בלתי נתפסות.

מכיוון שכל נתב שנרכש בשנים האחרונות מתהדר בתמיכה בUPNP שמופעלת בדרך כלל כברירת מחדל, הבעיה די חמורה.
מומחי אבטחה מנסים לשכנע אנשים מזה שנים שנתב NAT הוא לא Firewall, אבל רוב האנשים לא מבחינים בהבדל. מבחינתם אם הם מאחורי נתב הם בטוחים והנתב הוא זה שיספוג את ההתקפות.

אז זהו, שלא.
למעשה, ווקטור ההתקפה הזה מנצל את האמון שאנחנו רוכשים למחשבים בתוך הרשת.
למשל, שרותים מקומים רבים מאפשרים התחברות מהמחשב המקומי בלבד (ובודקים שההתחברות מגיעה מהמחשב המקומי). הפעלת פלאש תמימה (ונסתרת) יכולה לעקוף את ההגנה הזו בקלילות (ואם פלאש עדיין לא תומך בקישוריות UDP/TCP, הוא בטח יתמוך בגרסאות הבאות).

מומלץ לנטרל את התמיכה בUPNP בנתב שלכם.

ההתקפה הודגמה בGnuCitizen.

שרת החינוך שוברת שתיקה

אליבה דה טמקא, שרת התינוך יולי תמיר "שוברת שתיקה" והצטרפה למשא ומתן על סיום השביתת המרצים שנמשכת כבר 86 ימים.
מה שלא ברור לי בדיוק זה למה רק עכשיו מוציאה השרה את האצבע.
איפה היא היתה עד עכשיו?

TransferJet

סוני הכריזה על תקן חדש ופרטי לתקשורת אלחוטית בשם TransferJet.
בניגוד לWireless USB שמגיע למהירות של 480 מגה ביט לשניה למרחק של עד שלושה מטרים, ו110 מגה ביט למרחק של עד עשרה מטרים, הסטנדרט של סוני מגיע למהירות של 560 מגה ביט לשניה ממרחק של שלושה סנטימטרים.
קראתם טוב.

הרעיון הוא ליצור פרוטוקול פשוט שישמש להעברת נתונים אוטומטית בין מכשירים, נניח – שימו את המצלמה ליד הטלוויזיה, והיא כבר תעביר לטלוויזיה לבד את התמונות.
רוצים לסנכרן את נגן הMP3? שימו אותו ליד המחשב והמחשב כבר יעביר אליו לבד את הנתונים.
נשמע טוב, עד שחושבים על זה טיפה יותר:
הוא יעביר את הכל? מה עם שירים שכבר נמצאים על המכשיר?
ומה אם אני דווקא רוצה להעביר בכיוון השני?

אין ספק שסוני, שאחראית להצלחות מסחררות כמו המינידיסק, פורמט הדחיסה Atrac (שסוני הפסיקה את התמיכה בו), Memory stick – סטנדרט לאיכסון, דומה לדיסק-און-קי, רק שאף אחד לא משתמש בו), sdds (סטנדרט קולנועי לצליל דינמי, שסוני כבר לא תומכת בו) ועוד – מבקשת לשחזר את הישגי העבר ולפתח תקן מיותר חדש.

TorrentLeech2RSS חוזר

אחרי ניג'וסים ונדנודים, החברים בTorrentLeech בדקו את TorrentLeech2RSS ואישרו אותו לשימוש (כאילו, יכלתי לשחרר אותו בלי לומר להם, אבל אז הם היו משעים לי שוב את החשבון).
אז בקיצור, מי שרוצה להוריד, שיתכבד ויפנה לבלוג של הפרוייקט.