מדריך – איך להגדיר כרטיסי רשת חיצוניים על VirtualBox

ביקשו, אז אני מספק. פוסט מאוד מאוד מאוד מחשביסטי. אפילו יותר מאשר הקודם. פוסט גם ארוך. תהנו 🙂

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

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

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

בבסיס הכיוון אנחנו עומדים לעבוד עם מצב כרטיס רשת שנקרא “Host Interface”. במצב הזה הכרטיס של המכונה המתארחת מתחבר בחיבור peer to peer לכרטיס מיוחד על המכונה המארחת. הכרטיס המיוחד צריך להיות מסוג tap. זהו בדיוק אותו סוג של חיבור ש-OpenVPN משתמש בו.

הפעולה הראשונה שצריך לעשות, מתוך הנחה שאתם לא מריצים את VirtualBox כ-root, היא לייצר ממשק tap. ל-VB יש פקודה שזו בדיוק מטרתה. היא נקראת VBoxAddIF. לכו תקראו את ההסבר עליה. אנחנו עומדים להגיד למכונה לייצר, באופן אוטומטי, את ההמשק הזה בזמן עליית המכונה. אחד החסרונות המרכזיים של שימוש ב-tap בפרט, ובממשק peer to peer בכלל, היא שיכולים להיות לנו רק שני מחשבים על כל ממשק. מכיוון שאחד המחשבים חייב להיות המחשב המארח, זה אומר שאנחנו צריכים לייצר ממשק כזה עבור כל מחשב וירטואלי שיש לנו בנפרד. אל חשש – לייצר ארבעה זה לא הרבה יותר עבודה מאשר לייצר אחד.

דבר ראשון אנחנו צריכים להגיד למחשב לייצר את הממשק באופן אוטומטי כאשר המערכת עולה. אנחנו נייצר שני ממשקים כאלו, ועל כן נוסיף את השורות הבאות לקובץ ‎/etc/network/interfaces:

auto vbox0 vbox1
iface vbox0 inet static
        pre-up VBoxAddIF vbox0 sun
        address 10.173.154.1
        netmask 255.255.255.252
        post-down VBoxDeleteIF vbox0

iface vbox1 inet static
        pre-up VBoxAddIF vbox1 sun
        address 10.173.154.5
        netmask 255.255.255.252
        post-down VBoxDeleteIF vbox0

השורה הראשונה אומרת לדביאן להעלות את הממשקים כאשר המערכת עולה. הפקודה pre-up מורצת מייד לפני שהממשקים מקונפגים. למעשה, במקרה שלנו, הפקודה הזו יוצרת את הממשקים האלו יש מאין ברגע שדביאן מחליט שהוא צריך אותם. הפרמטר האחרון בפקודה, sun, הוא שם המשתמש שלי. צריך, כמובן, להחליף את זה בשם המשתמש שבו אתם משתמשים. באותו אופן, השורה של post-down מוחקת את הממשקים כאשר לא צריך אותם יותר. כתובת ה-IP נבחרה עם netmask צר ככל האפשר (במקרה זה – עם מקום לבדיוק שני מחשבים), כדי להקטין את הסיכוי להתנגשות עם מספרים אמיתיים שבהם תרצו להשתמש. ניתן להגדיר עוד ממשקים כרצונכם, ולהגדיל ב-4 את מספר ההתחלה בכל פעם. אין שום מניעה (ואפילו יש עדיפות קלה עד בלתי מורגשת) להשתמש במספרים המדוייקים שאני משתמש בהם. בכל מקרה, השתמשו במספרים שמוגדרים ע”י RFC-1918.

כעת צריך להכנס להגדרות של VirtualBox ולהגיד לו שאנחנו רוצים כרטיס מסוג host interface, לתת לו שם של כרטיס לשימוש (vbox0, vbox1 וכו’). יש לשים לב לא לתת לשתי מכונות את אותו שם, או שלא ניתן יהיה להדליק אותן בו זמנית. באותה הזדמנות שאנחנו כבר פה, כדאי לשמור בצד את המספר ש-VirtualBox נתן לכרטיס בתור ה-Mac address שלו. אנחנו נצטרך את המספר הזה יותר מאוחר (אפשר בלי, אבל אני פרנואיד). את המקום שבו VB מבקש פקודות להעלאה והורדה של הממשק אפשר להשאיר ריקות – אנחנו העלנו את הממשק כשהמערכת עלתה.

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

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

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

הפעולה השניה שאנחנו צריכים לעשות, וגם אותה חשוב לעשות ישר בהתחלה, הוא להכנס ל-‎/etc/default/dhcp3-server ולהגדיר את אלו כרטיסי רשת השרת משרת. זה ימנע ממנו מלנסות לתת כתובות על כרטיסי הרשת האמיתיים של המחשב, ובכך להרוס למחשבים אחרים את הקישוריות. בקובץ אנחנו צריכים להגדיר שורה שאומרת, פחות או יותר:

INTERFACES="vbox0 vbox1"

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

כדי ששרת dhcp ממש יצליח לתת כתובות, אנחנו צריכים להגדיר לו את הרשתות שאותן הוא משרת. לפני שאנחנו עושים את זה, אנחנו נעשה עוד שינוי קטן שמטרתו היא גם לאפשר לנו לגשת למכונה על פי שם. מכיוון שמדרך הטבע השם של המכונה לא עומד להיות רשום באף DNS, אנחנו נגדיר אותו בקובץ ההגדרות המקומי. הבחר לכל מכונה שם. למשל, אני מריץ מכונת OpenBSD, ועל כן קראתי לה obsd. מכיוון שחיברתי אותה לממשק vbox1, היא צריכה להיות ברשת שהגדרנו קודם. למעשה, היא צריכה להיות עם כתובת של אחת יותר מאשר המכונה שלנו. על כן אני מוסיף לקובץ ‎/etc/hosts את השורה הבאה:

10.173.154.6    obsd

כעת אפשר לחזור להגדרות של dhcp. נערוך את הקובץ ‎/etc/dhcp3/dhcpd.conf. דבר ראשון נוודא שהשורה שאומרת “authorative” היא עם הערה. נוסיף לו את החלק הבא:

subnet 10.173.154.4 netmask 255.255.255.252 {
  option domain-name-servers 212.150.49.10, 62.90.42.110;
  option domain-name "internal";
  option routers 10.173.154.5;
  default-lease-time 600;
  max-lease-time 7200;
}

host obsd {
  hardware ethernet 08:00:17:6C:81:D2;
  fixed-address obsd;
}

החלק הראשון מפרט את התכונות של ה-subnet. הוא כולל את שרתי ה-DNS (תעתיקו ממה שכתוב לכם ב-‎/etc/resolv.conf), מי הנתב שמקשר את הרשת החוצה (הכתובת של המכונה המארחת על אותו ה-subnet) ואורכי הזמן שלו ניתנת הכתובת. מה שלא כתוב שם, שבד”כ כן כתוב, זה מרחב הכתובות שאותו נותנים. הסיבה היא שאנחנו, מתוך אותו נסיון למנוע משרת ה-dhcp שאנחנו מקימים לפגוע בקישוריות של אחרים, לא מחלקים כתובות באופן דינמי. במקום זה, אנחנו קושרים את הכתובת שנתנו למכונה הוירטואלית בשלב הקודם אל הכתובת הפיזית של כרטיס הרשת שלה. זה התפקיד של החלק השני.

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

בשלב זה כבר יש לכם את כל מה שאתם צריכים כדי שהמכונה הוירטואלית תקבל כתובת IP, ושאתם תוכלו לתקשר איתה. כל מה שנותר כרגע הוא לאפשר לה להתחבר לאינטרנט. כמו VB, אנחנו נעשה את זה באמצעות NAT. אנחנו צריכים לעשות שני דברים. הראשון הוא להגיד למכונה שתהיה ראוטר, והשני זה שתהיה NAT.

את הפעולה הראשונה עושים ע”י זה שמורידים את ההערה מהשורה בקובץ ‎/etc/sysctl.conf:

# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.conf.default.forwarding=1

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

$ echo 1 > /proc/sys/net/ipv4/ip_forward

כל מה שנותר לעשות הוא להגדיר NAT. אתם, כמובן, מחזיקים firewall על המכונה שלכם, נכון? אם לא, שימו את הקובץ הזה ב-‎/etc/init.d, תיצרו ספריה בשם ‎/etc/iptables, כוונו את הפיירוול שלכם לתצורה הנכונה ואז תריצו iptables-save > /etc/iptables/active. כל מה שנותר לעשות הוא לרשום את הסקריפט שירוץ כל פעם שהמחשב עולה, לפני שהרשת עולה (“update-rc.d start 37 S .‎”. שימו לב: הנקודה חשובה!). עכשיו החוקים שהגדרתם יופעלו בכל פעם שהמחשב עולה, ואתם תהיו מוגנים.

כך או כך, לחוקים של ה-firewall צריך להוסיף כמה חוקים. דבר ראשון, המכונה הוירטואלית חייבת להיות מסוגלת להגיע לשרת ה-DHCP שלכם. אם אתם בעיקרון חוסמים תקשורת נכנסת (מומלץ בחום), יש להוסיף את החוקים הבאים:

iptables -A INPUT -i vbox+ -p udp --dport bootps -j ACCEPT

זה יאפשר למכונה המתארחת לבקש ולקבל כתובת IP מהמכונה המארחת. החוק השני שצריך להוסיף קשור ברשות לצאת החוצה. אם אתם מחזיקים FORWARD Policy שחוסם תקשורת (שוב, מומלץ בחום), יש להוסיף את החוקים הבאים:

iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i vbox+ -o ppp+ -j ACCEPT

השורה הראשונה דואגת לזה שתקשורת שההתחלה שלה כבר אושרה, תמשיך להיות מאושרת.
השורה השניה אומרת “תאפשר לכל תקשורת שמגיעה דרך כל כרטיס רשת שהשם שלו מתחיל ב-vbox ואמורה לצאת דרך כרטיס שהשם שלו מתחיל ב-ppp לעבור”. יכול שתצטרכו התאמות לשם הכרטיס שאיתו יוצאים, או להוסיף כמה חוקים כאלו לכמה כרטיסים.

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

iptables -A POSTROUTING -t nat -o ppp+ -j MASQUERADE

אם הכל עובר בשלום, אתם אמורים להיות מסוגלים להתקשר מהמכונה הוירטואלית שלכם החוצה כמו תחת NAT, אבל גם לתקשר אליה מהמכונה המארחת.

תיקון/הערות בתגובות

שחר