אבטחת המיילים באמצעות SPF

המיילים שלכם או של הלקוחות מגיעים ישירות אל הספאם? או שמופיע לידם סימן שאלה עם "אי אפשר לוודא את השולח"? הנה ההסבר המלא.

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

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

בדיוק כמו ב-HTTP, יש לנו headers. רוצים לראות? הכנסו לג'ימייל שלכם וביחרו מייל אקראי , לחצו על שלושת הנקודות וביחרו ב-Show Original:

תפריט המייל המלא בג'ימייל

מה נראה אחרי שנלחץ על זה? ראשית את מה שאנו רואים בהודעה – אבל מה שיותר מעניין הוא מה שיש בתחתית. ה-Headers (מעכשיו אני כותב הדרים).

טקסט דוגמה של מייל עם Headers

בדיוק כמו ב-HTTP. גם בפרוטוקול SMTP יש הדרים. ההדרים האלו לא נראים ללקוח אבל הם משפיעים מאוד על איך שהמייל נראה. למשל, אנחנו יכולים לפרט מה הקידוד שאותו אנחנו רוצים או את רמת הדחיפות של המייל:

דוגמה של X-Priority ו-Content Type

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

ממי המייל נשלח?

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

<?php     
$to_email = '[email protected]';
$subject = 'IMPORTANT MESSAGE';
$message = 'This is some spammy kaka';
$headers = "Reply-To: Numenore <[email protected]>\r\n";
$headers .= "Return-Path: Numenore <[email protected]>\r\n";
$headers .= "From: Numenore <[email protected]>\r\n";
$headers .= "Organization: `uk.gov.il\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/plain; charset=utf-8\r\n";
$headers .= "X-Priority: 3\r\n";
$headers .= "X-Mailer: PHP". phpversion() ."\r\n";
$res = mail($to_email,$subject,$message,$headers);
var_dump($res);
?>

שרת המייל ת-מ-י-ד יקבל את המייל הזה. עם ההדרים והכל. אם אני שולח את זה משרת וובי, הוא יקבל ב-Recieved את ה-IP של השרת ואת מה שהגדרנו בהוסט. במקרה הזה אפשר לראות שאני שולח את המייל מכתובת מקומית ומ-IP אישי שלי. אז שרת הדואר קיבל אותו, ומה הוא יעשה איתו? אם אתם משתמשים בג'ימייל, ברגע שהם רואים שרת מייל שלא מוגדר לו hostname, הם משגרים אותו אחר כבר כבוד אל תיבת הספאם:

מייל שמגיע עם אזהרת ספאם הישר לתיבת הספאם של ג'ימייל

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

ג'ימייל לא יכול לוודא שאתה השולח: Gmail couldn't verify that XXX actually sent this message and not a spammer

אם גם אתם מקבלים הודעות כאלו על מיילים שנשלחים מהאתר/דומיין שלכם – יש מה לעשות. כאמור מייל הוא לא וודו אפל, הוא בסך הכל פרוטוקול אחר. המיילים מגיעים לשרת אך הוא מסווג אותם כספאם. למה? ב דרך כלל כי חסר להם SPF. ואחרי ההקדמה הארוכה הזו, זה הזמן לספר על SPF Header.

SPF Header

זו דרך ותיקה ומאוד פשוטה לוידוא השולח. איך זה עובד? אני מציב ברשומת ה-DNS שלי (כן) שורה פשוטה ביותר שאומרת משהו פשוט: "רק שרת המייל שנמצא בהוסט הזה, או ב-IP הזה, יכול לשגר מיילים בשמי". למשל, שימו לב ל-hebdevbook.com, האתר שלי – יש לו רשומת טקסט כזו.

~ nslookup  -type=txt hebdevbook.com
Server:		192.168.5.1
Address:	192.168.5.1#53

Non-authoritative answer:
hebdevbook.com	text = "v=spf1 +a +mx +ip4:192.116.71.76 include:relay.mailchannels.net ~all"

Authoritative answers can be found from:
השורה הרלוונטית: v=spf1 +a +mx +ip4:192.116.71.76 include:relay.mailchannels.net ~all

מה השורה הזו אומרת? היא אומרת שאני משתמש ב-spf ואך ורק שרת מייל שנמצא בכתובת 192.116.71.76 או בהוסט relay.mailchannel.net יכול לשלוח מיילים בשם הדומיין הזה.

כששרת מייל מקבל מייל שמגיע, כביכול, מכל כתובת שהיא hebdevbook.com, הוא מבצע שאילתת DNS מסודרת לחפש אחר רשומת ה-txt של ה-spf. אם הוא מצא אותה, הוא מסתכל על ה-Recieved ומשווה ביניהם. מתאים? מעולה. זה לא ספאם. אם מדובר בג'ימייל, אז הוא לא ישגר את המייל אל תהומות הספאם או יציג את סימן השאלה המציק ליד שם השולח.

אפשר לראות את זה בהדרים של המייל כפי שהוא מתקבל בג'ימייל. מייל שעבר את המבחן, יציג את השורה הזו: Received-SPF: pass. אם הוא לא מציג pass – הוא לא עבר. הוא יכול להכשל בצורה ׳רכה׳ ואז יופיע natural או ׳קשה׳ ואז יופיע fail. אבל כל תוצאה חוץ מ-pass היא כשלון.

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

  1. לבדוק שיש לכם SPF על הדומיין, באמצעות שאילתת nslookup -type=txt YOURDOMAIN.COM או איזה בודק אונלייני כמו http://spf.myisp.ch/ למשל.
  2. במידה ואין, להוסיף. במידה ויש – לבדוק שההנחיות המופיעות בו רלוונטיות לשרת המייל שלכם.
  3. במידה ויש ומשהו מתחרבש, להסתכל בהדר ולראות אם יש Received-SPF: pass. במידה ואין למרות שהכנסתם SPF לדומיין, זה הזמן לבדוק מה קרה ובשביל זה יש את החלק הבא.

הסבר יותר מעמיק על רשומת ה-SPF

זה לא נורא מורכב, זה רק נראה ככה. אני אדגים פה. ראשית יש לי את הגרסה שאני משתמש בה. אחר כך יש לי את הפלוסים. כל פלוס אומר: "מה שבא אחרי, עובר". למשל: 192.116.71.76+ יגרום לכל מייל שנשלח משרת שזו כתובתו לעבור.

a – זה קיצור ל-top level domain. אם למשל כתובת המייל שלי היא: [email protected] ואני שולח משרת מייל שהוא hebdevbook.com, הבדיקה תעבור.

mx – כנ"ל, אבל עם mx record שיש ברשומת ה-DNS שלכם.

ip4 – כל שרת שמשתמש בכתובת הזו יכול לשלוח מייל בשם המתחם.

ip6 – אותו דבר כמו ip4, רק עם ip6 כי אנו חייבים להתקדם.

include – כתובת הוסט של שרת מייל.

עד כאן הפלוס, עכשיו תור ה-~. שזה סימן שאומר – כל מה שיש אחריו? תכשיל אבל לא כשלון מהדהד, שים אותו בספאם במטותא ממך אבל אל תירה על מנת להרוג. מה זה all? זה אומר "כל השאר". כלומר נתתי הנחיות לשרתים שמותר להם לשלוח (באמצעות הפלוס). כל השאר? להכשל ברכות. אם אתם ממש רוצים לגרום להם להכשל באכזריות, זה הזמן להשתמש בסימן מינוס. אבל מומלץ שלא לעשות את זה כי דיבאגינג.

כמובן שזה לא המאמר האחרון שיש על אבטחת מיילים, יש עוד הרבה לדעת. DKIM, DMARC ועוד מנגנונים. אבל SPF זה הצעד הראשון והחשוב.

פוסטים נוספים שכדאי לקרוא

פתרונות ומאמרים על פיתוח אינטרנט

יישום של nonce על מנת להגן מפני התקפות injection

בפוסט הקודם הסברתי על hash עם CSP על משאבי inline – שזה נחמד ומעולה אבל פחות ישים בעולם האמיתי שבו בדרך כלל התוכן ה-inline (בין

גלילה לראש העמוד