איך להגדיר גדר אש (Firewall) ב-Iptables כדי להגן על תנועת התקשורת בין השרתים שלך

הקדמה

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

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

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

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

דרישות מוקדמות

להתחיל, יש לך צורך בשני שרתים Ubuntu 22.04 חדים. הוסף חשבון משתמש רגיל עם הרשאות sudo בכל שרת. כדי לעשות זאת, עקוב אחרי המדריך שלנו להגדרת השרת הראשוני של Ubuntu 22.04 הגדרת שרת ראשוני של Ubuntu 22.04 שלנו.

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

שלב 1 — הגדרת חומת אש

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

המדריך עוקב אחרי תחביר הפקודות של iptables. iptables מותקן אוטומטית ב-Ubuntu 22.04 באמצעות גרסת nftables, כך שלא תצטרך להתקין חבילות נוספות.

באמצעות nano או עורך הטקסט האהוב עליך, פתח את הקובץ /etc/iptables/rules.v4:

  1. sudo nano /etc/iptables/rules.v4

הדבק את התצורה ממדריך התבנית של החומה:

/etc/iptables/rules.v4
*filter
# אפשר כל תעבורה יוצאת, אך הורד תעבורה נכנסת ותעבורה שמועברת לברירת המחדל
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]

# שרשרות מותאמות אישית לפרוטוקול
:UDP - [0:0]
:TCP - [0:0]
:ICMP - [0:0]

# תעבורה מקובלת של UDP

# תעבורה מקובלת של TCP
-A TCP -p tcp --dport 22 -j ACCEPT

# תעבורה מקובלת של ICMP

# מדיניות קבלה סטנדרטית
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A INPUT -i lo -j ACCEPT

# הורדת חבילות לא תקפות
-A INPUT -m conntrack --ctstate INVALID -j DROP

# העבר תעבורה אל שרשראות ספציפיות לפרוטוקול
## אפשר רק חיבורים חדשים (חיבורים שנפתחו וחיבורים קשורים כבר טופלו)
## עבור TCP, בנוסף רק אפשר חבילות SYN חדשות מאחר וזהו השיטה היחידה והחוקית
## להקיל על כל דבר שפלט אל נקודה זו
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
-A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP
-A INPUT -p icmp -m conntrack --ctstate NEW -j ICMP

# מסרב על כל דבר שנכשל עד נקודה זו
## נסה להיות ספציפי כמה שאפשר עם הודעת דחייה
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
-A INPUT -j REJECT --reject-with icmp-proto-unreachable

# אשר את השינויים
COMMIT

*raw
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT

*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT

*security
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT

*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT

שמור וסגור את הקובץ. אם אתה משתמש ב־nano, לחץ על Ctrl+X כדי לצאת, אז כאשר יתבקש, לחץ Y ואז Enter.

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

שלב 2 — גלה את היציאות שמשמשות על ידי השירותים שלך

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

ניתן להשתמש בכלי netstat כדי לגלות זאת. מכיוון שהיישום שלך תקשורת מסתיימת רק מעל IPv4, נוסיף את הארגומנט -4, אך ניתן להסיר אותו אם אתה משתמש גם ב-IPv6. הארגומנטים האחרים שתצטרך כדי למצוא את השירותים הפועלים שלך הם -p, -l, -u, -n, ו--t, שתוכל לספק כ--plunt.

ניתן לפרק את הארגומנטים האלו כך:

  • p: Show the PID and name of the program to which each socket belongs.
  • l: Show only listening sockets.
  • u: Show UDP traffic.
  • n: Show numeric output instead of service names.
  • t: Show TCP traffic.
  1. sudo netstat -4plunt

על השרת שלך, הפלט ייראה כמו זה:

Output
Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1058/sshd tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 4187/nginx

העמוד המודגש הראשון מציג את כתובת ה-IP והיציאה ששירות המודגש לסיומו של השורה מאזין עליה. כתובת ה-IP המיוחדת 0.0.0.0 אומרת שהשירות בשאלה מאזין לכל הכתובות הזמינות.

על שרת המסד נתונים שלך, הפלט ייראה כמו זה:

  1. sudo netstat -4plunt
Output
Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1097/sshd tcp 0 0 192.0.2.30:3306 0.0.0.0:* LISTEN 3112/mysqld

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

שים לב לערכים שאתה מוצא בשלב זה. אלו הפרטים הרשתיים שתצטרך להתאים את התצורה של הגדרות האש שלך.

על השרת שלך, עליך לוודא שהיציאות הבאות נגישות:

  • פורט 80 על כל הכתובות
  • פורט 22 על כל הכתובות (כבר נכלל בכללי הגנה בגידול)

שרת בסיס הנתונים שלך יהיה עליך לוודא שהפורטים הבאים נגישים:

  • פורט 3306 על הכתובת 192.0.2.30 (או הממשק הקשור אליו)
  • פורט 22 על כל הכתובות (כבר נכלל בכללי הגנה בגידול)

שלב 3 — להתאים את כללי הגנת הגישה לשרת האינטרנט

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

  1. sudo nano /etc/iptables/rules.v4

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

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

/etc/iptables/rules.v4
*filter
. . .

# תעבורת TCP מקובלת
-A TCP -p tcp --dport 22 -j ACCEPT
-A TCP -p tcp --dport 80 -j ACCEPT

. . .

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

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

בדוק את קובץ הכללים שלך לשגיאות תחבורת התחבורה:

  1. sudo iptables-restore -t < /etc/iptables/rules.v4

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

  1. sudo service iptables-persistent reload

שלב 4 – כוונת מדיניות הגבה של השרת בסיס הנתונים

על השרת שלך, עליך לאפשר גישה לפתח 3306 בכתובת ה-IP הפרטית של השרת שלך. במקרה זה, הכתובת הייתה 192.0.2.30. תוכל להגביל את הגישה שמיועדת לכתובת זו במיוחד, או תוכל להגביל את הגישה על ידי התאמה לפני הממשק שמוקצה לכתובת זו.

כדי למצוא את ממשק הרשת שמשויך לכתובת זו, הפעל ip -4 addr show scope global:

  1. ip -4 addr show scope global
Output
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 inet 203.0.113.5/24 brd 104.236.113.255 scope global eth0 valid_lft forever preferred_lft forever 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 inet 192.0.2.30/24 brd 192.0.2.255 scope global eth1 valid_lft forever preferred_lft forever

האזורים המודגשים מראים שהממשק eth1 משויך לכתובת זו.

בשלב הבא, תכוון את כללי הגבה בשרת המסדים שלך. פתח את קובץ הכללים עם הרשאות sudo על שרת המסדים שלך:

  1. sudo nano /etc/iptables/rules.v4

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

כדי להגביל גישה בהתבסס על הכתובת האמיתית בשאלה, תוכל להוסיף את הכלל כמו כן:

/etc/iptables/rules.v4
*filter
. . .

# תעבודת TCP מקובלת
-A TCP -p tcp --dport 22 -j ACCEPT
-A TCP -p tcp --dport 3306 -d 192.0.2.30 -j ACCEPT

. . .

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

/etc/iptables/rules.v4
*filter
. . .

# תעבודת TCP מקובלת
-A TCP -p tcp --dport 22 -j ACCEPT
-A TCP -p tcp --dport 3306 -i eth1 -j ACCEPT

. . .

שמור וסגור את הקובץ כאשר תסיימו.

בדוק תקלות תחביר עם הפקודה הזו:

  1. sudo iptables-restore -t < /etc/iptables/rules.v4

כאשר תהיו מוכנים, הטעו מחדש את כללי הגנת האש:

  1. sudo service iptables-persistent reload

שני השרתים שלך צריכים להיות מוגנים כעת בלי להגביל את זרימת הנתונים הנדרשת ביניהם.

סיכום

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

כדי לקבל מידע נוסף על אש ו־iptables בפרט, ראה את המדריכים הבאים:

Source:
https://www.digitalocean.com/community/tutorials/how-to-set-up-an-iptables-firewall-to-protect-traffic-between-your-servers