טיפים חיוניים לאבטחת Docker באירוח עצמי
אבטחו את השירותים שאתם מארחים בעצמכם — מהגנה ועד ניטור!
תוכן העניינים
- 🧗♀️ לאמיצים
- 🔄 ריקוד ה־
:latest - 🔐 ניהול סודות: הדרך הנכונה
- 🌐 סכנת הרשת
- 🛡️ בקרות גישה
- 🔍 ניטור ואימות
- ⏰ טיפים שמתעלמים מהם לעיתים קרובות
- 🚀 רשימת בדיקה לפרודקשן
- 📚 קריאה נוספת
🧗♀️ לאמיצים
אם אתם מארחים בעצמכם שירותי Docker, האבטחה היא באחריותכם מקצה לקצה — אין ספק ענן שיגן עליכם מסריקות פורטים או מקונפיגורציה מרושלת. בין אם אתם מעלים אפליקציות ברשת הביתית ובין אם אתם שוכרים VPS מספקים כמו Vultr, DigitalOcean, Linode, AWS, Azure או Google Cloud, תצטרכו להקשיח את המערכת — ואז לוודא שעשיתם את זה נכון.
במדריך הזה נעבור על אבטחת Docker — מטכניקות פחות מוכרות ועד טכניקות שקשה לבצע נכון; נבחן canary tokens, אמצעי אחסון לקריאה בלבד, כללי חומת אש, סגמנטציה והקשחה של הרשת, הוספת פרוקסי מאומת ועוד.
נשווה גם בין רשתות ביתיות לסביבות ענן ציבורי, ונראה איך להגדיר פרוקסי עם אימות בסיסי באמצעות Nginx. בסוף יהיו לכם כמה אפשרויות להרחיק את כל ה־riff-raff (חברים, משפחה, ולפעמים אפילו את עצמכם…)
זה המון דברים! אבל חלק גדול מהם קשור זה בזה, ואתם יכולים לבחור רק את מה שרלוונטי ביותר למערכת שלכם. 🍀
🔄 ריקוד ה־:latest
שמירה על images מעודכנים חיונית לאבטחה. עם זאת, הסתמכות על :latest עלולה להכניס שינויים שוברים או builds פגיעים בלי שלב בדיקה.
הדרך הבטוחה לעדכן
שלבו פקודות עדכון עם pull או build, כדי לרענן את ה־images במכוון, ואז בצעו restart בחלון זמן שבו תוכלו להבחין בתקלות.
#!/bin/bashdocker compose pull && \ docker compose up -dנעילת גרסאות לעומת Latest
בחירת הגרסה שאליה נועלים היא איזון בין יציבות לאבטחה. הנה כמה אסטרטגיות נפוצות:
# ... # Exact version pinning, best for critical services image: postgres:17.2
# Patch version pinning, good for non-critical services image: postgres:17.2
# Major version pinning, perfect for hobby projects image: postgres:17
# Yolo, avoid if possible image: postgres:latestהשתמשו ב־Dependabot או ב־Renovate כדי לפתוח PRs לעדכונים שאפשר לבדוק. עבור כל דבר שהייתם מצטערים לבנות מחדש בשתיים לפנות בוקר, נעלו לגרסה או ל־digest ספציפיים ותנו לאוטומציה להודיע לכם מתי הגיע הזמן להתקדם.
ספרו לי אילו כלים אתם הכי אוהבים כדי לשמור על Docker images מעודכנים!
🔐 ניהול סודות
יש דרכים רבות לנהל סודות, אבל אחד הכללים החשובים ביותר שכדאי להיצמד אליהם הוא: לעולם אל תקודדו סודות ישירות בתוך ה־Docker images שלכם ואל תבצעו להם commit ל־git. זו אחת מטעויות האבטחה הנפוצות ביותר, היא יוצרת סיכון לטווח ארוך, וקשה לתקן אותה.
אחסון מאובטח של סודות הוא נושא רחב עם אפשרויות רבות — מקובצי .env, דרך Docker secrets, 1Password/Bitwarden, ועד מנהל סודות כמו HashiCorp Vault או AWS Secrets Manager.
תצטרכו לבחור את רמת ההשקעה והאבטחה ה”נכונה” למקרה השימוש שלכם.
יצירת סודות חזקים
הנה סקריפט קטן ליצירת סודות חדשים עבור קובץ .env:
#!/bin/bashgenerate_secret() { local length=${1:-30} local generate_length=$((length + 4)) openssl rand -base64 "$generate_length" | tr -d '+=/\n' | cut -c1-"$length"}
[ -f .env ] && { echo ".env file already exists!"; exit 1; }
cat > .env << EOLPOSTGRES_PASSWORD=$(generate_secret)JWT_SECRET=$(generate_secret 64)SESSION_KEY=$(generate_secret 24)REDIS_PASSWORD=$(generate_secret 20)UNSAFE_PLACEHOLDER=__WARNING_REPLACE_RANDOM_TEXT__EOL
echo "New .env file generated with secure random values!"Canary Tokens
Canary Tokens הם דרך מצוינת לזהות אם הסודות שלכם נחשפו (ונעשה בהם שימוש). הם כמו חוטי־מעידה שאפשר להוסיף לכל קובץ, כתובת URL או אסימון רגישים.
שקלו להציב אותם לצד הסודות שבאמת מדאיגים אתכם: קובצי .env, משתני CI, מנהלי סיסמאות, תיקיות גיבוי ופרטי גישה לענן. אל תהפכו את זה לתיאטרון; הציבו חוטי־מעידה במקומות שתוקף אמיתי, או טעות עתידית שלכם, עלולים לגעת בהם.
יש סוגים רבים של “אסימוני” canary שאפשר לבחור מתוכם — אסימוני AWS, מספרי כרטיסי אשראי מזויפים, קובצי Excel ו־Word, קובצי Kubeconfig, פרטי גישה ל־VPN, ואפילו קובצי sql dump יכולים לכלול חוט־מעידה!
שיטות מומלצות ל־Canary Token
- להציב בכל מקום: בכל קובץ
.env, בכל pipeline של CI/CD ובכל “מנהל סודות” שעולה בדעתכם.- הציבו קובץ
passwords.xlsxאוpasswords.docxבתיקיית הבית שלכם. - הוסיפו פרופיל AWS בשם
billing_prod, כשהסוד שלו הוא canary token. - צרו קובץ
private.keyבתיקיית~/.sshשלכם. - צרו dump מסוג Canary SQL בשם
all_credit_cards.sqlבתיקיית~/backupsשלכם.
- הציבו קובץ
- לנטר: הגדירו כללים או התראות בדוא”ל כדי לזהות הפעלה של canary token.
שדרוג מ־.env ל־MacOS Keychain
למשתמשי Mac, אחת האפשרויות הפשוטות ביותר היא להשתמש ב־Keychain.
הנה דרך פשוטה לאוטומציה של טעינת סודות מ־OSX keychain, עם תמיכה ב־TouchID, ובאופן מאובטח מעט יותר מקובצי .env.
קרדיט מקורי: Brian Hetfield ו־Jan Schaumann.
### Functions for setting and getting environment variables from the OSX keychain ###### Adapted from: https://www.netmeister.org/blog/keychain-passwords.html andOriginal credit: [Brian Hetfield](https://gist.github.com/bmhatfield/f613c10e360b4f27033761bbee4404fd) and [Jan Schaumann](https://www.netmeister.org/).
# Use: get-keychain-secret SECRET_ENV_VARfunction get-keychain-secret () { security find-generic-password -w -a ${USER} -D "environment variable" -s "${1}"}
# Use: set-keychain-secret SECRET_ENV_VAR# You will be prompted to enter the secret value!function set-keychain-secret () { [ -n "$1" ] || print "Missing environment variable name"
# prompt user for secret echo -n "Enter secret for ${1}" read secret [ -n "$secret" ] || return 1
( [ -n "$1" ] || [ -n "$secret" ] ) || return 1 security add-generic-password -U -a ${USER} -D "environment variable" -s "${1}" -w "${secret}"}source ~/keychain-secrets.sh
# Load Env vars into the current shellexport AWS_ACCESS_KEY_ID=$(get-keychain-secret AWS_ACCESS_KEY_ID);export AWS_SECRET_ACCESS_KEY=$(get-keychain-secret AWS_SECRET_ACCESS_KEY);# Note: If an attack can run `env` in your shell, then these secrets could be exposed!#!/usr/bin/env bashsource ~/keychain-secrets.sh
# Specify all secrets for this projectAWS_ACCESS_KEY_ID=$(get-keychain-secret AWS_ACCESS_KEY_ID) \AWS_SECRET_ACCESS_KEY=$(get-keychain-secret AWS_SECRET_ACCESS_KEY) \ "$@"
# Note: Using a shell wrapper helps prevent secrets from staying# around in the environment. And it's safe to commit.
# Usage:# ./scripts/env-run.sh docker compose up -d# ./scripts/env-run.sh docker run -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS ...🌐 סכנת רשת
רשתות מותאמות אישית ופורטים פנימיים
בידוד נכון של שירותים באמצעות רשתות Docker הוא דרך חשובה לצמצום משטח התקיפה שלכם.
היזהרו כשאתם פותחים חורים ברשת! העברת פורט אחת שהוגדרה לא נכון עלולה להסתיים רע מאוד.
כברירת מחדל, שירותים ברשת LAN פרטית לא יהיו חשופים לאינטרנט — צריך להעביר במפורש פורטים מהנתב שלכם.
Docker ב־LAN
בין שאתם מפתחים שמריצים שרתי פיתוח באופן מקומי ובין שאתם מארחים שירותים עצמאית מהרשת המקומית שלכם, הנחות לגבי מודל הרשת של Docker עלולות לגרום לצרות.
מפתחים מופתעים לעיתים קרובות לגלות שהשיטות ה”מסורתיות” לאבטחת שרתי Linux (iptables, הגבלת אפשרויות sysctl של tcp/ip) עלולות להיכשל בשקט במארחי Docker! זה נכון במיוחד כש־מארחים עצמאית — או מריצים בסביבת רשת ביתית טיפוסית. (ולמי שלא שמע עד עכשיו: זה עלול לאפשר גישה לקונטיינרי פיתוח ב־MacBook שלכם!!!)
⚠️ אזהרה מס’ 1: פורטים שפורסמו על ידי Docker עלולים לעקוף את כללי חומת האש שחשבתם שמגינים על המארח, במיוחד עם UFW ב־Ubuntu/Debian. זה לא הופך כל כלל חומת אש לחסר תועלת, אבל המשמעות היא ש־“UFW אומר deny” אינו הוכחה. ראו issue #690: Docker עוקף את כללי חומת האש של ufw.
⚠️ אזהרה מס’ 2: קשירת פורטים לכתובות IP מקומיות (למשל,
-p 127.0.0.1:8080:80) היא ברירת המחדל הנכונה, אבל בגרסאות Docker Engine שקדמו ל־28.0.0 היו מקרים שבהם מארחים באותה רשת L2 עדיין יכלו להגיע לפורטים שפורסמו על localhost. Docker מתעד את הסייג הזה במדריך פרסום הפורטים שלו, וההרגל לאמת באמצעות nmap שמופיע בהמשך עדיין חשוב.
אם הופתעתם לגלות את זה, גם אני!
קשירת פורטים לכתובות IP מקומיות היא עדיין נוהג טוב ויש לה השפעה משמעותית בסביבות ענן מנוהלות וברשתות שהוגדרו במיוחד.
דוגמת Docker Compose
הנה דוגמה לקובץ docker-compose.yml שקושר את השירות app אל 127.0.0.1:8080 ומחבר את שני הקונטיינרים לרשת המותאמת אישית backend.
networks: backend:
services: app: networks: - backend ports: # Bind to localhost if possible - "127.0.0.1:8080:8080" # ... other settings database: image: postgres:17.1 # No ports needed; accessible inside backend network. networks: - backendשיטות עבודה מומלצות לרשתות
- 🏆 אל תפרסמו שום פורט לאחרונה גיליתי שזה שימושי יותר מכפי שאפשר לצפות! כשמשתמשים ברשת בעלת שם (bridge), לקונטיינרים יש גישה לא מסוננת זה לזה. הם מתנהגים כאילו הם נמצאים מאחורי רשת מקומית (שער NAT).
- זה לא אפשרי בכל תרחיש, אבל עשוי להיות שימושי לקונטיינרים שמריצים משימות אצווה, או שניגשים אליהם בעיקר דרך
attachאוexec.
- זה לא אפשרי בכל תרחיש, אבל עשוי להיות שימושי לקונטיינרים שמריצים משימות אצווה, או שניגשים אליהם בעיקר דרך
- 🥇 השתמשו ברשתות Docker כדי לבודד קונטיינרים ולשלוט באילו קונטיינרים יכולים לתקשר זה עם זה.
- 🥉 השתמשו בקשירה ל־localhost: אף שהיא לא מושלמת, בדרך כלל עדיף לקשור פורטים לכתובת loopback (למשל,
127.0.0.1:8080:80). רק הקפידו לאמת את ההגדרה שלכם.
🛡️ בקרות גישה
בקרות גישה הן חלק קריטי באבטחת שירותי Docker. זה כולל הגבלת היכולות וההרשאות של קונטיינרים, הגבלת הגישה ל־Docker socket ועוד.
הגבלת יכולות של קונטיינרים
נוהג טוב נוסף בתחום בקרות הגישה הוא להגביל את היכולות של הקונטיינרים. כך מצמצמים את רדיוס הפגיעה של כמה סוגי איומים, מהסלמת הרשאות ועד חטיפת תעבורה. זו לא מערכת כוח, אבל היא מסירה הרשאות שרוב הקונטיינרים מעולם לא היו צריכים.
מהן capabilities? הרשאות או יכולות בעלות שם, המוגדרות על ידי ליבת Linux. (דף ה־capabilities מכיל רשימה מלאה.) הן כוללות דברים כמו CAP_CHOWN (שינוי בעלות על קבצים), CAP_NET_ADMIN (הגדרת ממשקי רשת), CAP_KILL (הריגת כל תהליך) ועוד רבות אחרות.
יש שתי דרכים לקבוע אילו יכולות נדרשות:
- ניסוי וטעייה: בשיטה הזו, איטית אך יעילה, מתחילים בלי שום יכולות ומוסיפים אותן בחזרה, אחת־אחת, עד שהאפליקציה עובדת.
- חיפוש עבודה קודמת: חפשו “
project-namecap_dropDockerfile”, או “project-namecap_dropdocker-compose.yml”, כדי לבדוק אם מישהו אחר כבר עשה את העבודה עבורכם. LLM יכול להציע נקודת פתיחה, אבל התייחסו להצעה כאל ניחוש עד שתבדקו את הקונטיינר ותקראו את תיעוד האימג׳.
שיטות עבודה מומלצות ליכולות
- השמיטו את כל היכולות: השתמשו ב־
cap_drop: [ ALL ]כדי להשמיט מהקונטיינר את כל יכולות Linux. - ללא הרשאות חדשות: השתמשו ב־
security_opt: [ no-new-privileges=true ]כדי למנוע מהקונטיינר לקבל הרשאות חדשות.
services: database: image: postgres:17.1 networks: [ db-network ] security_opt: - no-new-privileges:true cap_drop: - ALL cap_add: - CHOWN - DAC_READ_SEARCH - FOWNER - SETGID - SETUID db-admin: image: dpage/pgadmin4:4.1 networks: [ db-network ] ports: - "8081:80" # ... other settingsnetworks: db-network:כעת השירותים שלכם יכולים לתקשר זה עם זה דרך הרשת db-network. Docker Compose ייצור את הרשת הזו באופן אוטומטי.
השתמשו באפשרות --external/external: כדי להצטרף ל־רשת קיימת מראש. השמיטו אותה כדי ליצור רשת חדשה.
גישה ל־Docker Socket
⚠️ אזהרה: docker.sock הוא למעשה גישת מנהל מערכת ל־host
⚠️ האפשרות `:ro` לא משפיעה על קלט־פלט שנשלח דרך ה־socket!
היא רק מבטיחה שנתיב ה־socket עצמו יותקן לקריאה בלבד. קריאות ה־API שנשלחות דרך ה־socket עדיין יכולות ליצור קונטיינרים, לטעון נתיבים מה־host ולעשות דברים מרגשים מאוד אחרים, שככל הנראה לא התכוונתם להאציל.
שיטות עבודה מומלצות ל־Socket
- 🥇 הימנעו מטעינת ה־Docker socket, כנראה יש חלופה טובה יותר.
- 🫣 אם אין ברירה, הציבו לפניו proxy מצומצם ואפשרו רק את נקודות הקצה של ה־API שהאפליקציה באמת צריכה. בדקו את פרויקט
docker-socket-proxy, שנוצר במקור על ידי Tecnativa: docker-socket-proxy. לאחר מכן ודאו שהקריאות שנחסמו אכן נחסמות. - 🤢 טוב, אולי שיתוף שלו מקובל בסביבת בדיקות בעלת רמת אמון גבוהה מאוד ו־סיכון נמוך.
חסימת מדינה!
לפעמים זה שימושי, אבל זו לא גבול אבטחה אמיתי.
אנחנו מדברים על ישות גיאופוליטית, לא על המוזיקה…
אם אתם מארחים אפליקציות בעיקר עבור משפחה וחברים מקומיים, תוכלו לחסום תעבורה ממדינות שאינכם מצפים לקבל מהן תעבורה. לחלופין, אפשר לאפשר תעבורה רק ממדינות שמהן אתם כן מצפים לקבל אותה. זה מפחית רעש; זה לא עוצר VPN-ים, proxies, botnets או אנשים סבלניים.
הנה סקריפט שחוסם את כל התעבורה מסין:
curl -fsSL https://www.ipdeny.com/ipblocks/data/countries/cn.zone | \ while read line; do ufw deny from $line to any; doneבאופן דומה, אפשר לאפשר תעבורה רק מארצות הברית:
curl -fsSL https://www.ipdeny.com/ipblocks/data/countries/us.zone | \ while read line; do ufw allow from $line to any; doneהקשחת מארח Proxy של CloudFlare
אם שרת הבית שלכם מוגן מאחורי כתובת IP של CloudFlare (במצב proxy), תוכלו להגביל את הגישה לכתובות ה-IP של CloudFlare בלבד ולרשת המקומית שלכם.
זה דומה במקצת לחסימת מדינה! שהוזכרה למעלה, אבל עם שליטה הדוקה הרבה יותר.
ufw default deny incoming # Block all incoming!!!ufw default allow outgoing # Allow all outgoingufw allow ssh # Allow SSH
# Allow access for local subnet (preferably dedicated DMZ/VLAN for hosted services)ufw allow from 10.0.0.0/8 to any port 443
# Allow CloudFlare IPscurl -fsSL https://www.cloudflare.com/ips-v4 | \ while read line; do ufw allow from $line to any port 443; done# Add IPv6 support# curl -fsSL https://www.cloudflare.com/ips-v6 | \# while read line; do ufw allow from $line to any port 443; doneכדי לבדוק שינויים המבוססים על מיקום גאוגרפי, VPN עם נקודות יציאה במדינה הרצויה יכול להיות שימושי. מידע נוסף נמצא בסעיף ניטור ואימות.
אבטחה בשכבת האפליקציה
אחרי שהקשחתם את אבטחת הרשת והמארח, ייתכן שתגלו שיש עוד עבודה.
עכשיו צריך לחשוב על שכבת ה״אפליקציה״ של השירותים עצמם.
האם למסד הנתונים יש סיסמה תקפה? האם הקונטיינר מטפל אוטומטית ב-HTTPS ובתעודות? האם האפליקציה כוללת אימות מובנה? האם יש הגבלות על כתובות האימייל שיכולות להירשם? האם קיימים פרטי התחברות או משתני סביבה ברירת מחדל שצריך לשנות?
הדרך היחידה לדעת היא לבדוק. במקרה הזה, התחילו ב-README ובקבצים חשובים נוספים כמו docker-compose.yml, Dockerfile ו-.env.*. בדקו גם את הפרויקט עצמו וגם, רצוי, את השירותים התומכים בו (למשל Postgres, Redis וכדומה).
Reverse Proxy
שכבת הגנה נוספת היא אימות בסיסי (basic auth). אל תשתמשו בו בלי HTTPS. בשירותים ישנים, הצבת basic auth לפני נתיב ניהול מספיקה לעיתים קרובות כדי לעצור בקשות אקראיות וסורקים לא מאומתים מלגשש ישירות בשירות.
location /admin { auth_basic "Restricted Access"; auth_basic_user_file /etc/nginx/.htpasswd; proxy_pass http://internal_admin:80; proxy_set_header X-Real-IP $remote_addr;}צרו פרטי התחברות:
htpasswd -c /etc/nginx/.htpasswd adminעם proxy של basic auth, לתוקפים יש מכשול נוסף — שם משתמש וסיסמה — לפני שהם מגיעים לשירות הפנימי שלכם.
אפשרות נוספת היא להשתמש בשירות כמו Traefik או Caddy, שיכול להפוך את הגדרת ה-HTTPS וה-basic auth לאוטומטית עבורכם.
אם אתם רוצים לנהל דומיינים ושירותים רבים באמצעות ממשק גרפי, אני ממליץ על Nginx Proxy Manager.
🔍 ניטור ואימות
זהו השלב החשוב ביותר, וזה שהכי נוטים לדלג עליו. אתם יכולים להחזיק את חומת האש הטובה ביותר, את הרשת הטובה ביותר ואת נוהלי העבודה הטובים ביותר, אבל אם אינכם מאמתים אותם, אין לכם מושג אם הם עובדים.
בנוסף, היכרות עם קומץ פקודות בלבד — או עם המקום שבו אפשר למצוא אותן — עשויה להיות ההבדל בין מניעת פריצה לבין התמודדות איתה. התחושה שאתם האקרים היא רק בונוס. (לפרטים ולדוגמאות, דלגו לסעיף ניטור ואימות.)
אל תסמכו, אמתו פעמיים
בדיקת הפורטים שלכם
⚠️ חשוב: אין לסרוק מארחים שאינם בבעלותכם.
בין אם אתם נמצאים ברשת ביתית ובין אם ב-VPS, תרצו לדעת אילו פורטים פתוחים לעולם.
יש 2 דרכים לעשות זאת:
- לבדוק את הרשת (
nmap,masscan) - לשאול את מערכת ההפעלה (
lsof,netstat,ss)
בדיקה מחוץ לרשת שלכם
תצטרכו את כתובת ה-IP הנוכחית (הציבורית) שלכם. קל להשיג אותה באמצעות שירותים כמו ifconfig.me: curl https://ifconfig.me. לחלופין, חפשו אותה בלוח הבקרה של ספק האחסון שלכם.
curl -fsSL https://ifconfig.me# --> CURRENT PUBLIC IPאחרי שיש לכם את כתובת ה-IP הציבורית, עליכם להתחבר לרשת חיצונית. תוכלו להשתמש במחשב של חבר, בטלפון או בנקודת גישה סלולרית של 5G, או בשרת ייעודי אצל ספק אירוח.
target_host="$(curl -fsSL https://ifconfig.me)"
# Note: Ensure `target_host` is the desired IP
# Scan specific ports:nmap -A -p 80,443,8080 --open --reason $target_host# Top 100 ports:nmap -A --top-ports 100 --open --reason $target_host# All portsnmap -A -p1-65535 --open --reason $target_hostבדיקה בתוך הרשת שלכם
תרגלו שימוש ב-nmap: סרקו את הרשת המקומית שלכם או אחד מהשרתים שלכם, ובדקו את הנתב, המדפסת והמקרר החכם.
דוגמאות לפקודות סריקה
# Scan your localhost for all open portsnmap -sT localhost
# Scan your machine’s private IP for servicesnmap -sV 192.168.1.10
# Find service details on your networknmap -sn 192.168.0.0/24nmap -sn 10.0.0.0/24# Or on a docker 172.18.0.1/16nmap -sn 172.18.0.1/16% nmap -A --open --reason 192.168.0.87
Starting Nmap 7.95 ( https://nmap.org ) at 2025-01-06 13:51 MSTNmap scan report for dev02.local (192.168.0.87)Host is up, received syn-ack (0.0067s latency).Not shown: 995 closed tcp ports (conn-refused)PORT STATE SERVICE REASON VERSION22/tcp open ssh syn-ack OpenSSH 9.6p1 Ubuntu 3ubuntu13.5 (Ubuntu Linux; protocol 2.0)| ssh-hostkey:|_ 256 {FINGERPRINT} (ED25519)80/tcp open http syn-ack Caddy httpd|_http-server-header: Caddy|_http-title: Dev02.DanLevy.net443/tcp open ssl/https syn-ack|_http-title: Dev02.DanLevy.net1234/tcp open http syn-ack Node.js Express framework|_http-cors: GET POST PUT DELETE PATCH|_http-title: Dev02.DanLevy.net (application/json; charset=utf-8).Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .Nmap done: 1 IP address (1 host up) scanned in 13.36 secondsהצגת פורטים פתוחים
כדאי להכיר את lsof — הוא זמין ב-MacOS וב-Linux. הוא מציג את מצב הרשת ואת פעילות הדיסק ברמת פירוט גבוהה.
# Monitor specific portsudo lsof -i:80 -Pn
# ניטור חיבורים במצב ESTABLISHEDsudo lsof -i -Pn | grep ESTABLISHED# הצגת LISTENsudo lsof -i -Pn | grep LISTEN
# כדי לראות שמות רשת במקום כתובות IP (בדיקות DNS הפוכות עשויות להיות איטיות מאוד)sudo lsof -i -P | grep LISTEN
# ניטור כל חיבורי הרשתsudo watch -n1 "lsof -i -Pn"פלט לדוגמה

ניטור קבצים
כדי לזהות אילו תהליכים משתמשים ברוחב הפס הגדול ביותר של הכונן הקשיח, אפשר להשתמש ב־iotop:
sudo iotopכדי לראות שינויים בקבצים בודדים, אפשר להשתמש ב־inotifywait ב־Linux או ב־fswatch ב־MacOS:
זה יכול לעזור לזהות התנהגות לא מורשית או חריגה, לפי תיקייה או בכל המערכת.
# Monitor all file changes in a directorysudo inotifywait -m /path/to/directoryב־MacOS אפשר להשתמש ב־fswatch:
התקינו באמצעות brew install fswatch
fswatch -r /path/to/directory⏰ טיפים שלעתים קרובות מתפספסים
-
הגבלת קצב לניסיונות אימות ולכל נקודת קצה קריטית אחרת. בין אם באמצעות המודול
limit_reqשל Nginx ובין אם באמצעותfail2banלגישה ב־SSH, האטת ניסיונות brute-force היא כנראה רעיון טוב. אני אומר כנראה כי בעידן ה־IPv6 והבוטנטים הזולים, ובכן, זה כבר לא מה שהיה. -
השתמשו ב־Volumes לקריאה בלבד היכן שאפשר:
services: webapp: volumes:
- ./config:/config:ro
בשילוב עם שיטות עבודה מומלצות אחרות — משתמשים שאינם root והרשאות מינימליות לתיקיות — אפשרות ה־`:ro` ב־volume mount מספקת שכבת הגנה נוספת מפני שינויים מקריים ומפני ניסיונות כתיבה מסוימים מתוך הקונטיינר. היא אינה מגינה על ה־host מפני תהליך שכבר מחזיק בהרשאות רחבות יותר.
3. **בדקו באופן שגרתי את הגישה של הקונטיינרים**. אם קונטיינר לא זקוק ל־secret, לפורט או ל־mount מסוימים, הסירו אותם!
4. **היזהרו מה־Riff-Raff של ה־WiFi** אני בטוח שלעולם לא תמסרו את סיסמת ה־WiFi שלכם, במיוחד לא לאיזה טיפוס מפוקפק, נכון? טוב, חוץ מכמה חברים... אוקיי, אולי גם למשפחה. לעולם אי אפשר לדעת אילו אפליקציות מותקנות אצלם ואילו מהן עלולות לשתף את ה־SSID והסיסמה שלכם עם כל העולם.
### רשת ביתית לעומת ספק ציבורי לעומת מנהור
1. **בידוד וירטואלי/DMZ**: בשרתים ביתיים, העבירו אותם ל־VLAN נפרד או ל־DMZ, אם אפשר. כך המכשירים הפנימיים שלכם לא יהיו חשופים לפגיעה אפשרית שמקורה בצד השרת. - השתמשו בנתב נפרד או ב־VLAN נפרד עבור השרת הביתי. - השתמשו ברשת WiFi נפרדת עבור השרת הביתי. - השתמשו ב־subnet נפרד עבור השרת הביתי.
2. **ספקי ענן**: Hetzner, Vultr, DigitalOcean, Linode, AWS, Azure ו־Google Cloud מספקים יכולות Firewall שונות. - חלק מהספקים והשירותים חוסמים פורטים כברירת מחדל. חלקם מציעים אפשרויות הפעלה או תוספים. בדקו את התיעוד של ספק השירות שלכם. - ספקים רבים מציעים שירותי ניטור מתקדמים וזיהוי איומים.
3. **VPN ומנהור**: שקלו להשתמש באפשרות דמוית VPN או בשירות מנהור כדי לחבר שירותים באופן מאובטח דרך האינטרנט, בלי לחשוף אותם לאינטרנט הציבורי. - TailScale, ngrok, ZeroTier. - WireGuard, OpenVPN.
{/* 3. **Hardening Against Internal/Lateral Attacks**: One infected device can compromise an entire network. Segmenting Docker services on custom networks, using hardware, UFW rules, and blocking unneeded ports can all help reduce risk (when properly configured.) */}
## 🚀 רשימת בדיקה לפרודקשן
- [ ] **Secrets**: כל ה־secrets נוצרו באופן אקראי ונשמרים בצורה מאובטחת- [ ] **עדכונים**: אסטרטגיית עדכון הקונטיינרים מתועדת ואוטומטית. (גם כמה פקודות בקובץ טקסט זה בסדר.)- [ ] **רשת**: רק הפורטים הנחוצים חשופים, ורשתות פנימיות מוגדרות.- [ ] **כללי Firewall**: ברירת המחדל היא חסימה, עם אישורים מפורשים; חסימות לפי מדינה אם נדרש.- [ ] **Reverse Proxy**: Nginx, Caddy או Traefik יכולים להוסיף שכבה של basic auth- [ ] **Canary Tokens**: מקמו אותם ליד הקבצים הרגישים ופרטי ההתחברות שבאמת הייתם בודקים אילו מישהו היה נוגע בהם.- [ ] **ניטור**: הכירו את המערכות שלכם באמצעות `nmap`, `lsof`, `inotifywait`, `glances` וכלים דומים.- [ ] **אסטרטגיית גיבוי**: נבדקה, רצוי אוטומטית, ומאוחסנת מחוץ לאתר.- [ ] **ההרשאות המזעריות הנדרשות**: משתמשים שאינם root בקונטיינרים, ו־Volumes לקריאה בלבד.
## 📚 קריאה נוספת
- [שיטות מומלצות לאבטחת Docker](https://docs.docker.com/develop/security-best-practices/)- [דף העזר של OWASP לאבטחת Docker](https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html)- [Benchmark של CIS ל־Docker](https://www.cisecurity.org/benchmark/docker)- [Canarytokens.org עבור Canary Tokens](https://canarytokens.org/)
## תודות
תודה לכמה משתמשי Reddit חדי־עין:
- <em className="cite">[u/JCBird1012](https://www.reddit.com/user/JCBird1012/) - [דיון](https://www.reddit.com/r/selfhosted/comments/1hv8jn6/comment/m5rvlzi/).</em>- <em className="cite">[u/Salzig](https://www.reddit.com/user/Salzig/)</em>- <em className="cite">[u/Myelrond](https://www.reddit.com/user/myelrond/)</em>- <em className="cite">[u/shrimpdiddle](https://www.reddit.com/user/shrimpdiddle/)</em>- <em className="cite">[u/troeberry](https://www.reddit.com/user/troeberry/)</em>
תודה שקראתם! אני מקווה שהמדריך הזה היה שימושי. אם יש לכם שאלות או הצעות, אתם מוזמנים לפנות אליי ברשתות החברתיות שלי למטה, או ללחוץ על הקישור `Edit on GitHub` וליצור PR! ❤️