SSD Nodes Learn Hosting plans →
מדריכים Matt Connorמאת Matt Connor · עודכן 2026-08-31

התקנת wg-easy עם Docker: מדריך הגדרה מלא

למדו להריץ WireGuard עם ממשק ניהול ב-Docker Compose. המדריך מסביר את הגדרות NET_ADMIN ו-sysctls הנדרשות, ואיך לעבור לגרסה 15 ללא שגיאות במשתני הסביבה.

מה אתם בונים

wg-easy הוא WireGuard עם ממשק אינטרנט, הפועל כמכולת Docker אחת. הוא מנהל עבורכם את ממשק ה-WireGuard ומוסיף ממשק דפדפן ליצירת לקוחות. כל לקוח שאתם יוצרים מקבל קובץ הגדרות וקוד QR, כך שטלפון מצטרף ל-VPN על ידי הפניית המצלמה אל המסך.

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

אתם זקוקים ל-KVM VPS עם כתובת IPv4 ציבורית, Docker Engine עם תוסף Compose, והרשאות root. וירטואליזציה של מכולות המשתפת את ה-kernel של המארח, כגון OpenVZ או LXC, בדרך כלל אינה יכולה לטעון את מודול ה-WireGuard, והמכולה תיכשל בהעלאת הממשק.

גרסה 15 העבירה את ההגדרות מחוץ למשתני הסביבה

רוב המדריכים שתמצאו נכתבו עבור wg-easy 14, שבה הגדרתם את WG_HOST לכתובת השרת שלכם ואת PASSWORD_HASH לגיבוב bcrypt של סיסמת הניהול, שניהם כמשתני סביבה. גרסה 15 היא שכתוב מלא. הערות המעבר הרשמיות מציינות במפורש שגרסה 15 אינה משתמשת באותם משתני סביבה כמו גרסה 14, וכי רובם הועברו ללוח הבקרה בממשק הניהול בדפדפן.

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

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

קובץ ה-compose

צרו ספרייה עבור ה-stack וכתבו לתוכה את קובץ ה-compose הרשמי. זהו הקובץ המקורי מהמקור (upstream), ללא שינויים.

sudo mkdir -p /etc/docker/containers/wg-easy
sudo curl -o /etc/docker/containers/wg-easy/docker-compose.yml \
  https://raw.githubusercontent.com/wg-easy/wg-easy/master/docker-compose.yml

תוכן הקובץ נראה כך:

volumes:
  etc_wireguard:

services:
  wg-easy:
    image: ghcr.io/wg-easy/wg-easy:15
    container_name: wg-easy
    networks:
      wg:
        ipv4_address: 10.42.42.42
        ipv6_address: fdcc:ad94:bacf:61a3::2a
    volumes:
      - etc_wireguard:/etc/wireguard
      - /lib/modules:/lib/modules:ro
    ports:
      - "51820:51820/udp"
      - "51821:51821/tcp"
    restart: unless-stopped
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    sysctls:
      - net.ipv4.ip_forward=1
      - net.ipv4.conf.all.src_valid_mark=1
      - net.ipv6.conf.all.disable_ipv6=0
      - net.ipv6.conf.all.forwarding=1
      - net.ipv6.conf.default.forwarding=1

networks:
  wg:
    driver: bridge
    enable_ipv6: true
    ipam:
      driver: default
      config:
        - subnet: 10.42.42.0/24
        - subnet: fdcc:ad94:bacf:61a3::/64

etc_wireguard הוא volume בעל שם המכיל את מפתח השרת ואת כל הלקוחות שתיצרו. בצעו גיבוי ל-volume זה, אחרת בנייה מחדש (rebuild) תמחק את כל ה-peers שלכם. אם אתם מעדיפים לראות את הקבצים הללו במערכת הקבצים של ה-host, החליפו אותו ב-bind mount, אך קראו תחילה על ההבדלים בין bind mounts לבין volumes בעלי שם לפני שתעשו זאת, כיוון שההרשאות מתנהגות בצורה שונה.

מדוע נדרשים NET_ADMIN, SYS_MODULE והגדרות sysctl

כברירת מחדל, מכולה אינה מורשית לגעת ב-stack של הרשת, וכל אחת מהשורות הללו מסירה חסימה ספציפית.

NET_ADMIN מאפשר למכולה ליצור את הממשק wg0, להקצות לו כתובת ולכתוב נתיבי ניתוב (routes). ללא הרשאה זו, המכולה עולה ואז קורסת בעת ניסיון העלאת הממשק, כיוון ש-ip link add wg0 type wireguard מחזיר Operation not permitted.

SYS_MODULE יחד עם ה-mount לקריאה בלבד של /lib/modules מאפשרים למכולה לטעון את מודול ה-kernel של WireGuard אם המארח (host) טרם טען אותו. המודול נמצא ב-kernel של המארח ולא בתוך ה-image, וזו הסיבה שתיקיית המארח חייבת להיות גלויה. ב-kernel מודרני המודול לרוב מובנה, וניתן לוודא זאת באמצעות sudo modprobe wireguard && echo ok על המארח.

net.ipv4.ip_forward=1 גורם ל-kernel להעביר (forward) חבילות מידע שאינן ממוענות למכונה עצמה. ללא הגדרה זו, לקוח מתחבר, ה-handshake מצליח, אך לאחר מכן כל חבילה המיועדת לאינטרנט נזרקת, ולכן ping 1.1.1.1 מגיע ל-timeout בעוד ה-VPN נראה מחובר.

net.ipv4.conf.all.src_valid_mark=1 הוא ההגדרה שמפתיעה משתמשים רבים. WireGuard מסמן את חבילות המידע היוצאות שלו כדי שלא ינותבו חזרה לתוך ה-tunnel. מנגנון סינון נתיב חוזר (reverse path filtering) קפדני מזהה חבילה שכתובת המקור שלה אינה תואמת לנתיב הצפוי וזורק אותה. הגדרת sysctl זו מורה ל-kernel לקבל חבילות מסומנות, וזה מה שמונע מ-tunnel מלא לשבש את עצמו.

הפעלת השירות ויצירת חשבון מנהל

cd /etc/docker/containers/wg-easy
sudo docker compose up -d
sudo docker compose logs -f

השתמשו ב-docker compose up וב-docker compose down, ולא ב-start וב-stop. המפתחים מזהירים כי הרצת start על מכולה שנוצרה בהגדרות שונות מותירה את הרשת במצב לא עקבי. אם ברצונכם שה-stack יחזור לפעול לאחר אתחול, restart: unless-stopped כבר מטפל בכך, והמאמר התנהגות העלייה של שירותי compose מסביר מה מדיניות זו מבטיחה ומה לא.

ממשק ה-web מאזין בפורט TCP 51821. בביקור הראשון יוצג דף הגדרה שבו תיצרו את חשבון המנהל ותאשרו את כתובת ה-host שבה ישתמשו הלקוחות כדי להגיע לשרת. כתובת ה-host הזו נכנסת לשורת ה-Endpoint בכל קובץ הגדרות של לקוח, לכן עליה להיות ה-IP הציבורי או שם ה-DNS של ה-VPS. אם הכתובת שגויה, קוד ה-QR שתעבירו לטלפון יפנה ליעד שאינו נגיש, וה-handshake לעולם לא יושלם.

דבר נוסף בנוגע לפורט זה: wg-easy 15 מסרב לעבוד עם HTTP רגיל אלא אם תגדירו INSECURE=true. גישה אליו באמצעות HTTPS עם תעודה לא מהימנה, או ביצוע TLS termination ב-reverse proxy לפניו, הן אפשרויות תקינות. גישה אליו באמצעות http:// עם הגדרות ברירת המחדל אינה אפשרית.

אל תחשפו את פורט ממשק המשתמש לאינטרנט

קובץ ה-compose חושף את פורט 51821 בכל ממשקי הרשת. מדובר בדף התחברות למערכת המסוגלת לנתב את התעבורה שלכם, ואין לחשוף אותו לציבור. חשיפת פורט ב-Docker כותבת חוקים לשרשרת ה-DOCKER, אשר נבדקת לפני ה-ufw, ולכן חוק חסימה ב-ufw לא יסגור אותו. מדובר במלכודת שחשוב להבין לעומק, והמאמר מדוע פורטים חשופים ב-Docker מתעלמים מ-ufw מסביר זאת במלואו.

הפתרון הפשוט הוא לקשור את ממשק המשתמש ל-loopback ולגשת אליו דרך מנהרת SSH:

    ports:
      - "51820:51820/udp"
      - "127.0.0.1:51821:51821/tcp"
    environment:
      - INSECURE=true

לאחר מכן, מהמחשב הנייד שלכם:

ssh -L 51821:127.0.0.1:51821 youruser@your.server.address

פתחו את http://127.0.0.1:51821 בדפדפן במחשב הנייד. התעבורה מוצפנת באמצעות SSH, הפורט אינו מגיב לאף גורם אחר, ו-INSECURE=true נשאר מאובטח כאן כיוון שקפיצת ה-HTTP הגלויה לעולם אינה עוזבת את ממשק ה-loopback.

פתיחת פורט UDP 51820 ובדיקת שני ה־firewalls

הפרוטוקול WireGuard דורש שפורט UDP 51820 יהיה נגיש מהאינטרנט. Docker מפרסם את הפורט, אך ספקי שירות רבים מציבים firewall רשתי נפרד לפני ה־VPS, ש־Docker אינו מודע לקיומו. יש לפתוח את הפורט בשני המקומות. אם אתם מנהלים את ה־firewall של המארח באמצעות ufw, המדריך כללי ufw בסיסיים ל־VPS הוא דרך קצרה יותר מאשר כתיבת חוקי nftables ידנית.

וודאו שהמכולה אכן מאזינה:

sudo ss -ulnp | grep 51820

עליכם לראות socket מסוג UDP במצב האזנה. אם השורה ריקה, המשמעות היא שהמכולה לא הצליחה להעלות את הממשק, ו־sudo docker compose logs wg-easy יציג את הסיבה לכך.

יצירת לקוח וסריקה שלו בטלפון

בממשק המשתמש, צרו לקוח ותנו לו שם שתוכלו לזהות מאוחר יותר, למשל שם המכשיר שאליו הוא שייך. wg-easy מקצה את כתובת ה-tunnel הפנויה הבאה ומייצר עבורכם את זוג המפתחות. כל שורת לקוח מציגה קוד QR וקובץ .conf להורדה.

התקינו את אפליקציית WireGuard הרשמית בטלפון, בחרו באפשרות להוסיף tunnel מקוד QR, וסרקו את הקוד שמופיע על המסך שלכם. ה-tunnel יופיע תחת השם שהקלדתם. הפעילו אותו, ושורת הלקוח בממשק תתחיל להציג מוני תעבורה וזמן handshake אחרון. ברגע שהטלפון מחובר ל-tunnel, הוא יכול להגיע לשירותים שלא פרסמתם לאינטרנט; כך טלפון יכול להמשיך להעלות קבצים ל-שרת תמונות בניהול עצמי מכל מקום, מבלי שלשרת יהיה פורט אחד פתוח לעולם. אותו טריק עובד גם עבור מדיה, ו-ספריית Jellyfin שעוצבה כספריית וידאו משנות ה-90 היא דבר נעים לגלישה מחדר מלון, בעוד היא נשארת פרטית בדיוק כפי שהייתה ב-LAN הביתי שלכם. התראות עובדות בכיוון ההפוך על גבי אותו tunnel, שכן שרת ntfy בניהול עצמי יכול לדחוף הודעה לטלפון ברגע שמשימת גיבוי נכשלת, מבלי לענות מעולם לבקשה מהאינטרנט הציבורי.

לקוח שלא מציג handshake לאחר הפעלתו אינו מגיע לשרת כלל. זה מצביע על בעיה בפורט UDP 51820, ב-firewall של ספק השירות או בכתובת ה-endpoint שמוטמעת בתוך ה-config. לקוח שמציג handshake אך ללא גישה לאינטרנט מצביע על בעיית forwarding או DNS.

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

מתי כדאי לעבור משימוש בממשק גרפי

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

אתם תיתקלו במגבלות הכלי כאשר תזדקקו להגדרה שהממשק אינו תומך בה. ניתוב בין אתרים (Site-to-site), שבו ה-AllowedIPs של עמית מכסה תת-רשת מרוחקת שלמה במקום כתובת בודדת, הוא בדרך כלל המחסום הראשון. מנהרות מפוצלות (Split tunnels) עם חוקי ניתוב פר-עמית, או קובץ הגדרות שנוצר על ידי כלי ה-provisioning שלכם, הם השלב הבא. בנקודה זו, הגדרה ידנית אינה קשה יותר, היא פשוט שונה, ו-המדריך הרשמי ל-WireGuard מציג את אותה מנהרה שנבנתה מ-wg0.conf. אם אתם מעדיפים להפסיק להריץ את ה-control plane בעצמכם, השוואה בין WireGuard ל-Tailscale מכסה את האפשרות המנוהלת. האם מדובר בעסקה משתלמת תלוי במה ששרת התיאום יכול להגיע אליו בפועל, ומומלץ לקרוא את מודל האמון של Tailscale לפני שאתם מוסרים לו את הרשת שלכם. עלות היא בדרך כלל השאלה הבאה, ו-מה שהתוכנית החינמית של Tailscale כוללת בפועל מספיק כדי שמשק בית או צוות קטן לא ישלמו דבר. מעבר לנקודה זו, החיוב מבוסס על מספר משתמשים ולא על מספר מכשירים, מה שמהווה מבנה עלות שונה משרת VPS שאתם כבר משלמים עליו, לכן העלויות של Tailscale לאחר חריגה מהתוכנית החינמית הוא הנתון שיש לבדוק לפני העברת צוות. למנהרה המלאה שבניתם יש שקול ישיר שם, שכן הגדרת ה-VPS כ-exit node ב-Tailscale מעניקה לכם את אותו ניתוב החוצה דרך השרת, באישור מתוך ה-admin console במקום בכתיבה ידנית לכל קובץ הגדרה של לקוח. גם למחסום תת-הרשת יש פתרון שקול, כיוון ש-פרסום רשת פרטית שלמה מה-VPS מעניק את הרשת הזו לכל מכשיר ב-tailnet ללא צורך בעריכת ה-AllowedIPs לכל עמית, מה שהוביל אתכם לעזוב את הממשק הגרפי מלכתחילה. אם אתם מעוניינים בלוח הבקרה ובניתוב ה-mesh האוטומטי אך לא בשרת תיאום של גורם חיצוני, הרצת שרת NetBird עצמאי על גבי VPS שומרת את ה-control plane על חומרה שבבעלותכם, במחיר של הגדרות DNS ו-TLS ש-wg-easy מעולם לא דרש מכם.

אם תחביר ה-compose לעיל היה החלק הלא מוכר ולא ה-WireGuard עצמו, יסודות Docker Compose על גבי VPS מסביר את מבנה הקובץ ואת הפקודות היומיומיות.

FAQ

מדוע wg-easy מתעלם מהמשתנים WG_HOST ו-PASSWORD_HASH שלי?

משתנים אלו שייכים לגרסה 14 של wg-easy. גרסה 15 היא שכתוב מלא, והמפתחים העבירו כמעט את כל התצורה ללוח הבקרה בממשק האינטרנט. המכולה אינה קוראת את המשתנים הללו, לכן היא עולה כרגיל ומבקשת ממך ליצור חשבון מנהל בביקור הראשון. הגדר את כתובת המארח (host) עבור הלקוחות בדף ההגדרה הראשונית.

האם אני זקוק ל-SYS_MODULE אם ה-kernel שלי כבר כולל את WireGuard?

לא. ה-SYS_MODULE וה-mount של /lib/modules קיימים כדי שהמכולה תוכל לטעון את המודול כאשר המארח לא עשה זאת. במארח שבו הפקודה sudo modprobe wireguard מצליחה כבר כעת, היכולת הזו אינה בשימוש. הסרתה היא צעד מומלץ להקשחת האבטחה, אך NET_ADMIN נדרש בכל מקרה.

הלקוח מתחבר אך אין אינטרנט. מה הבעיה?

לחיצת יד (handshake) ללא תעבורה מעידה כמעט תמיד על בעיית ניתוב (forwarding). ודא ש-net.ipv4.ip_forward=1 ו-net.ipv4.conf.all.src_valid_mark=1 עדיין נמצאים בקובץ ה-compose, שכן עותק שנערך ידנית נוטה לאבד אותם. אם הניתוב מופעל, בדוק את שרת ה-DNS שקיבל הלקוח. מנהרה ששולחת את כל התעבורה דרך ה-VPN אך מצביעה על שרת DNS שאינו נגיש נראית בדפדפן בדיוק כמו חיבור תקול.

כיצד אוכל לגבות את הלקוחות שלי?

הכול נמצא ב-volume בעל השם etc_wireguard, בתוך קובץ wg0.json. בממשק המשתמש קיים גם כפתור גיבוי שמייצא את אותם הנתונים. העתק את הקובץ הזה למקום מחוץ לשרת לפני כל שדרוג. שחזור מתבצע באמצעות העלאת הקובץ בשלב ההגדרה של מכולה חדשה.

האם ניתן להריץ את wg-easy מאחורי reverse proxy?

כן. הצב את ה-proxy לפני פורט TCP 51821, בצע שם TLS termination, והגדר את INSECURE=true במכולה כדי שתקבל את תעבורת ה-HTTP הפשוטה מה-proxy. השאר את פורט UDP 51820 חשוף ישירות, כיוון שתעבורת ה-VPN היא מסוג UDP ואינה עוברת דרך HTTP proxy.