בעקבות הפוסט הקודם שלי, שבו כתבתי על שרת http מהיר ויעיל, שאלו אותי איך בדיוק ליצור סביבת פיתוח מקומית שכוללת https. גם פה, מדובר בבעיה מוכרת שרבים מכירים את הפתרון לה אבל יש מצב שחלק לא והפוסט שלי בא לפתור בדיוק את זה.
אז להרים סביבה מקומית בפרוטוקול http זה קל ונעים. אבל לפעמים אנחנו צריכים סביבה מקומית ב-https ואז הענינים מסתבכים. מעבר לכך שבאמת https נראה ללא מעט אנשים כמו וודו, יש בעיות תמידיות עם מערכת ההפעלה ובסופו של דבר כשאנו מריצים סביבה מקומית, במקרה הטוב אנו רואים את המסך הזה:
מעבר לכך שזה מבאס, לא מעט פעמים אנחנו בכלל לא יכולים להתקדם (ללחוץ על next) בגלל הגדרות אבטחה שמגיעות מה-sysadmin ובכלל מדובר במשהו לא נעים.
למה זה קורה? HTTPS הוא פרוטוקול שמשתמש ב-Secure Socket Layer – ראשי התיבות הן SSL. הוא מאפשר לנו גישה מוצפנת לאתר. למה צריך גישה מוצפנת? כדי למנוע מכל מי שבאמצע להאזין. מי נמצא באמצע? למשל בעל הנתב או הרשת הסלולרית שבה אתם משתמשים, הממשלה או מיקי זוהר סקרן שרוצה לדעת אם אתם שובבים ונכנסים לאתרים בעייתיים ואפילו ברשת עצמה – נקודות שונות שהמידע שלנו עובר בהם. מעבר לעניין של הפרטיות – אם אנו מעבירים מספרי כרטיסי אשראי ונתונים אחרים, אנחנו לא רוצים שמישהו יציץ ויקח אותם. בגלל זה עוד ועוד אתרים עוברים ל HTTPS.
הסבר על המכניקה של HTTPS
האמת שדיברתי על זה (בעברית) בכמה דקות של הרצאה שיכולות לחסוך לכם את הקריאה בכנס רברסים. הנה, פה – החל מ 14:30:
איך ההצפנה עובדת בפועל? בתחילה הצפנה א-סימטרית (פה הסברתי יותר לעומק על זה). תהליך שנקרא SSL Handshake ובו מוחלפים המפתחות הציבוריים על מנת ששני הצדדים יוכלו לוודא שמדובר באמת בהם. אחרי כן מוחלף מפתח להצפנה סימטרית והתקשורת מתחילה.
אבל, מי מייצר את המפתחות הציבוריים? מפתחות הצפנה קל מאוד לייצר – מפתח ציבורי ומפתח פרטי לכל דומיין שהוא. זו הסיבה שבפרוטוקול של HTTPS גם מוגדר מי יכול ליצור את המפתח הציבורי הזה – רק מי שהורשה על ידי Root CA יכול להנפיק תעודה.
מה זאת אומרת? שימו לב למשל לתעודת האבטחה של internet-israel.com. מי שהוציא אותה, נכון לזמן כתיבת שורות אלו, היא קלאודפלייר. ומי שהסמיך אותה לתת את התעודה היא Baltimore CyberTrust Root
מדובר ב-root ca. אחת מרשימה מצומצמת של חברות שיכולות לתת הרשאה לחברות אחרות להנפיק תעודה. אם Root CA לא מאשרת את התעודה שלי – התעודה פשוט לא ולידית ונקבל התראות, אזהרות וקללות מהדפדפן. אנחנו חייבים שה-root ca יאשר לנו את תעודת ההצפנה. עבור אתרים אמיתיים יש לנו את Let's encrypt למשל. אבל הם מבצעים אימות של השרת. הם לא יכולים לאמת לנו את הדומיין 127.0.0.1 או את ה-IP שלנו.
הפתרון
אז מה עושים? הפתרון הוא להכניס למחשב שלנו root ca מזויף, שהוא כולו שלנו, שהוא זה שיאשר לנו את התעודה לסביבה הלוקלית. פעם זה היה מסובך. אבל הודות לכלי נפלא בשם mkcert, זה פשוט להפליא. הכלי יוצר לנו תעודת Root CA שנכנסת כהארד קוד למחשב שלנו ובאמצעותו אנו יכולים לחולל תעודות אבטחה לכל דומיין מקומי. כל תעודה שנוצרת עם הכלי משתמשת ב-mkcert root ca המקומי.
הפתרון עובד במק, לינוקס וגם חלונות. אני מדגים את זה על מק כי זה מה שיש לי פה.
התקנה
ראשית, מתקינים את mkcert. אני התקנתי עם brew באופן פשוט ויעיל באמצעות:
brew install mkcert
באתר של mkcert יש הסבר מפורט על התקנות בדרכים ובפלטפורמות אחרות.
אחרי כמה דקות, הכלי יותקן. השלב הבא הוא להתקין את ה-Root CA. פעולה חד פעמית ופשוטה:
mkcert -install
מייד אחרי ההרצה, יקפצו מלא בקשות לאישור ולא סתם הוספת Root CA היא פעולה שעלולה לחשוף את כל תעבורת ה-HTTPS שלנו לתוקף. במקרה הזה מדובר בכלי מקומי אבל צריך להבין את הסיכונים. אם מישהו יגנוב את תעודת האבטחה המזויפת, שנמצאת בתיקיה המקומית שלכם – התנועה שלכם עלולה להיות חשופה. מצד שני, אם מישהו השיג גישה למחשב שלכם – אתם גם ככה בבעיה. המיקום של תעודת האבטחה של ה Root CA ניתן לגילוי אם מקלידים את הפקודה mkcert -CAROOT. לידיעה.
הפעלה
ו… זהו! ההתקנה הסתיימה. עכשיו ניגשים לתיקית הפרויקט ויוצרים תעודת אבטחה. בגדול קובץ key וקובץ cert. איך? ככה:
mkcert -key-file key.pem -cert-file cert.pem 0.0.0.0 localhost 127.0.0.1 ::1 "example.dev"
בכל שרת המממש SSL, תצטרכו להגדיר key ו-cert ואלו הקבצים שיווצרו לכם. שימו לב שאתם יכולים להוסיף איזו כתובת IP ואיזו כתובת שרת שאתם רוצים (תצטרכו להצמיד אותה ל-localhost בקובץ ה-hosts שלכם כמובן).
למשל עם http-server, תקבלו https מיידי ובלי בעיות אם תריצו:
node ./node_modules/http-server/bin/http-server -S -C cert.pem
ב-express למשל תצטרכו להגדיר את המפתחות ב-http.serve:
const express = require('express');
const fs = require('fs');
const https = require('https');
const app = express();
app.get('/', function (req, res) {
res.send('hello world');
});
https
.createServer(
{
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem'),
},
app
)
.listen(3000, function () {
console.log(
'Example app listening on port 3000! Go to https://localhost:3000/'
);
});
הנה אתר לוקלי מוצפן ב-https!
אם תבחנו את ההצפנה היטב, תראו שה-Root CA הוא מזויף לגמרי:
בעבר התקנת Root CA למכונות לוקליות היתה באמת תהליך לא נעים. עכשיו זה הרבה יותר פשוט ונעים להרים סביבה לוקלית ב-HTTPS.
2 תגובות
וואו! מדהים!
יכול ממש להקל לי על החיים.
איך הוא עם וורדפרס?
אני משתמש בכלי שנקרא localWP שמייצר סביבות וורדפרס כאילו בקלות ממש. ובאמת האפשרות של https לא עובדת אצלו. פעם עבד, ועם עדכון כלשהו של macOS זה הפסיק לעבוד.
תודה רבה מעניין מאוד
אתה פשוט מאשר למחשב עוד ספק root של תעודות, שהוא בעצם אתה. והוא מספק לספק משנה אפשרות ליצור תעודות (שגם זה אתה).
הסיכון פה הוא ממש לא מעט.
הוספה קטנה לקובץ hosts ואתה עלול להיות חשוף…
סינכרון הפרוייקט עלול בטעות לייצא תעודות חתומות שהמחשב שלך מאמין להן באופן עיוור.
ושלא להמעיט בסיכון שכן הבאת, שאמנם מחייב ״גניבת קובץ״ מהמחשב, שזה לא פחות משכפול של מפתח מאסטר לכל דלתות המבצר, והנחתו במקום שמור. שזה בסדר, אבל תמיד כדאי שיהיו בעולם כמה שפחות מפתחות כאלו…
לדעתי כדאי להשתמש במחשב פיתוח בלבד.