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

מהירות נמוכה ב-WireGuard: איך לאבחן ולפתור

סובלים ממהירות נמוכה ב-WireGuard? בדרך כלל מדובר בבעיית MTU שגורמת לחבילות מידע להיחסם. מדריך זה מסביר איך לבצע אופטימיזציה ל-TCP MSS, לבדוק את הנתיב ולזהות צווארי בקבוק ב-CPU.

ממה נובעות מהירויות נמוכות ב-WireGuard

מהירויות נמוכות ב-WireGuard נובעות מאחד מארבעה גורמים, שאינם בעלי סבירות שווה. הראשון הוא MTU (יחידת שידור מרבית): המנהרה יוצרת חבילות מידע גדולות מדי עבור אחד הקישורים בנתיב, ולכן העברות קבצים גדולות נתקעות בעוד העברות קטנות נראות תקינות. השני הוא הנתיב עצמו, שהיווה מגבלה עוד לפני קיום המנהרה. השלישי הוא המעבד (CPU) בשרת VPS שיתופי קטן, שבו פעולות ההצפנה מתחרות על משאבים מול כל שאר האורחים על אותו מארח. הרביעי הוא החיבור של העמית (peer) עצמו.

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

כדאי לשלול תסמין אחד לפני כל פעולה אחרת. אם כל אתר חדש דורש מספר שניות כדי להתחיל להיטען ואז עובר במהירות מלאה, מדובר בפתרון שמות (name resolution) ולא בתפוקת נתונים. ל-DNS over WireGuard יש דפוסי כשל משלו, ושום שינוי ב-MTU לא יפתור אותם.

מדוע ה-MTU של WireGuard הוא 1420?

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

כותרת הנתונים של WireGuard היא בת 32 בתים: שדה סוג של 4 בתים, אינדקס מקבל של 4 בתים, מונה של 8 בתים, ותג אימות Poly1305 של 16 בתים. סביב אלו מתווספת כותרת UDP של 8 בתים. סביב אלו מתווספת כותרת ה-IP החיצונית, שהיא בת 20 בתים עבור IPv4 ו-40 בתים עבור IPv6. לכן, סך האנקפסולציה הוא 60 בתים כאשר ה-Endpoint שלכם הוא כתובת IPv4, ו-80 בתים כאשר הוא IPv6. דף פרוטוקול WireGuard מתעד את מבנה ההודעה שממנו נגזרים מספרים אלו.

wg-quick לא מנחש זאת. הוא קורא את ה-MTU של הממשק שמנתב ל-Endpoint שלכם, ואז מחסיר 80. בנתיב Ethernet רגיל של 1500 בתים, התוצאה היא 1420, וזהו הערך ש-ip link show wg0 מציג. הוא מחסיר 80 במקום 60 כדי שהערך יישאר בטוח גם אם נקודת הקצה תגיע אי פעם דרך IPv6, שם הכותרת החיצונית גדולה ב-20 בתים.

ChartMTU arithmetic for common underlays
The data behind this chart
[
  {
    "label": "Ethernet, IPv4 endpoint",
    "path_mtu": 1500,
    "encap_overhead": 60,
    "usable_wg0_mtu": 1440
  },
  {
    "label": "Ethernet, IPv6 endpoint",
    "path_mtu": 1500,
    "encap_overhead": 80,
    "usable_wg0_mtu": 1420
  },
  {
    "label": "PPPoE DSL, IPv4 endpoint",
    "path_mtu": 1492,
    "encap_overhead": 60,
    "usable_wg0_mtu": 1432
  },
  {
    "label": "Extra tunnel in the path",
    "path_mtu": 1400,
    "encap_overhead": 80,
    "usable_wg0_mtu": 1320
  }
]

אותן 4 שורות הן חשבוניות, לא מדידות. בנתיב נקי של 1500 בתים עם נקודת קצה מסוג IPv4, הערך 1440 היה מתאים, לכן ברירת המחדל של 1420 מותירה 20 בתים לא מנוצלים. מרווח זה הוא מכוון ואינו מהווה בעיה עבורכם.

השורה האחרונה היא הבעייתית. כאשר קישור כלשהו בנתיב מעביר רק 1400 בתים, מנהרה שעדיין מוגדרת ל-1420 תייצר חבילה חיצונית של 1500 בתים בכל מקטע מלא, שזה 100 בתים יותר ממה שהקישור יקבל. הערך שמתאים הוא 1320.

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

איך נראה MTU שגוי

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

  • ping דרך ה-tunnel עובד בכל גודל סטנדרטי.
  • התחברות SSH מסתיימת בהצלחה והקלדה מרגישה תגובתית.
  • curl -I https://example.com מחזיר כותרות (headers) באופן מיידי.
  • curl https://example.com על דף גדול נתקע לאחר כמה קילובייטים בודדים.
  • scp של קובץ גדול מתחיל ואז נעצר באחוז מסוים.
  • סשן SSH קופא ברגע שמריצים פקודה שמדפיסה כמות גדולה של פלט.

כל זה קורה מכיוון שחיבור TCP בונה מקטעים (segments) בגודל מלא רק כשיש לו נתונים רבים להעביר. ה-handshake והבקשה הראשונה נכנסים תחת כל MTU בנתיב. התקיעה מתחילה במקטע המלא הראשון, וזו הסיבה שהחיבור נראה תקין עד לנקודה שבה הוא הופך לבלתי שמיש.

חבילה חיצונית שגדולה מה-MTU של ה-link הבא בנתיב נתקלת באחד משני גורלים.

היא עוברת פרגמנטציה (fragmentation). נתב מפצל אותה והצד המרוחק מרכיב את החלקים מחדש. ההעברה עובדת אך היא איטית יותר, כיוון שאתם משלמים כעת בשתי חבילות במקום אחת, והמקבל מחזיק מצב (state) עד להגעת שתיהן. אובדן של פרגמנט אחד גורם לאובדן החבילה המקורית כולה, לכן נתיב עם 1% אובדן חבילות מתנהג כנתיב גרוע בהרבה. חומות אש רבות גם משליכות פרגמנטים של IP כחלק ממדיניות, מה שהופך תוצאה זו לתוצאה הבאה.

היא מושלכת, ואולי לא תקבלו על כך הודעה. נתב שאינו מבצע פרגמנטציה שולח הודעת ICMP (פרוטוקול הודעות בקרה באינטרנט) מסוג "fragmentation needed" בחזרה לשולח, עם ה-MTU שהוא מסוגל לקבל. אם הודעה זו מגיעה, מנגנון ה-path MTU discovery עובד והשולח מקטין את גודל המקטע שלו באופן עצמאי. רשתות רבות מסננות ICMP, ולכן לעיתים קרובות הוא לא מגיע. שום דבר אחר לא מדווח על האובדן. זהו ה-"black hole": החבילה יוצאת, שום דבר לא חוזר, לא מופיעה שגיאה באף לוג בשני הצדדים, וההעברה נתקעת עד שמשהו מגיע ל-timeout.

כיצד אמצא את ה-MTU הנכון?

מדדו את הנתיב, ולאחר מכן בצעו את החיסור. בדקו את תשתית הרשת (underlay) ולא את ה-tunnel; בצעו ping לכתובת הציבורית של השרת מהלקוח ואסרו על פרגמנטציה (קיטוע).

ping -M do -s 1472 -c 3 203.0.113.10

-M do מגדיר את ביט ה-DF (אל תקטע), כך שאף נתב בדרך לא רשאי לפצל את החבילה. -s הוא גודל ה-payload של ה-ICMP. חבילת IPv4 מלאה היא ה-payload הזה בתוספת 8 בתים של כותרת ICMP ו-20 בתים של כותרת IP, לכן -s 1472 מציב בדיוק 1500 בתים על הקו.

שלוש תוצאות הן בעלות משמעות. תשובות תקינות מצביעות על כך ש-1500 בתים עוברים ושה-MTU אינו הבעיה שלכם. שגיאה מקומית אומרת שממשק הרשת שלכם קטן יותר ממה שביקשתם:

ping: local error: message too long, mtu=1500

תשובה מנתב בדרך מספקת לכם את התשובה ישירות, ואפשר לעצור שם:

From 203.0.113.1 icmp_seq=1 Frag needed and DF set (mtu = 1492)

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

דוגמה לחיפוש בינארי, סבב אחר סבב

כל שורה היא פקודה שאתם מריצים בלקוח מול הכתובת הציבורית של השרת. ההערה מתעדת את התוצאה שהתקבלה.

ping -M do -s 1472 -c 3 203.0.113.10   # 100% loss, so 1500 is too big
ping -M do -s 1272 -c 3 203.0.113.10   # replies, so 1300 fits
ping -M do -s 1372 -c 3 203.0.113.10   # replies, so 1400 fits
ping -M do -s 1422 -c 3 203.0.113.10   # 100% loss, so 1450 is too big
ping -M do -s 1397 -c 3 203.0.113.10   # 100% loss, so 1425 is too big
ping -M do -s 1384 -c 3 203.0.113.10   # 100% loss, so 1412 is too big

ה-payload הגדול ביותר שעבר הוא 1372, לכן נתיב זה מעביר לפחות 1400 בתים ופחות מ-1412. קחו את הערך הבטוח. MTU של 1400 בנתיב, פחות 80 בתים של encapsulation, נותן MTU של 1320 עבור wg0.

tracepath מריץ את אותו חיפוש באופן אוטומטי, וכדאי להריץ אותו פעם אחת לפני שמתחילים בחיפוש ידני:

tracepath -n 203.0.113.10

השורה האחרונה שלו מדווחת על מה שנמצא:

     Resume: pmtu 1492 hops 12 back 12

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

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

sudo ip link set mtu 1320 dev wg0

נסו שוב את ההעברה שנתקעה. אם היא מסתיימת בהצלחה, הפכו את הערך לקבוע בבלוק ה-[Interface] של הלקוח:

[Interface]
PrivateKey = <client private key>
Address = 10.8.0.2/32
MTU = 1320
sudo wg-quick down wg0 && sudo wg-quick up wg0
ip link show wg0

ip link show wg0 אמור כעת להדפיס mtu 1320. אם הוא עדיין מדפיס את הערך הישן, wg-quick לא קרא את הקובץ שערכתם. ודאו שערכתם את /etc/wireguard/wg0.conf ושה-MTU נמצא תחת [Interface] ולא תחת [Peer], שם הוא מתעלם ממנו.

MTU הוא מאפיין של ממשק בודד והוא לעולם לא מנוהל במשא ומתן בין עמיתים (peers). הגדרתו בלקוח רק מקטינה את החבילות שהלקוח שולח. השרת ממשיך ליצור חבילות לפי ה-MTU של ה-wg0 שלו, לכן הורדות עדיין עלולות להיתקל ב"חור שחור" לאחר שהעלאות מתחילות לעבוד. הגדירו את הערך בשני הצדדים, או בצעו MSS clamping בשרת.

מדוע MSS clamping פותר בעיות TCP ולא שום דבר אחר

אם השרת מעביר תעבורה עבור עמיתיו, כפי שהוא עושה בכל הגדרת WireGuard VPS סטנדרטית המשתמשת ב-NAT (תרגום כתובות רשת), חוק אחד פותר את בעיות ה-TCP עבור כל עמית וחוסך מכם את הצורך לרדוף אחרי ערך ספציפי בכל לקוח שאינו בשליטתכם.

MSS (גודל מקטע מרבי) הוא אפשרות TCP שכל צד מציב בחבילת ה-SYN שלו כדי להצהיר מהו גודל המקטע שהוא מוכן לקבל. ביצוע clamping משכתב את האפשרות הזו בזמן אמת כדי להתאים ל-MTU האמיתי של הנתיב, כך ששני הצדדים מסכימים על מקטע קטן יותר לפני שנתונים כלשהם עוברים. זה עובד מכיוון שהתהליך מתרחש במהלך ה-handshake, ומכיוון שהוא אינו תלוי בהודעת ICMP שהנתיב כנראה חוסם.

בעזרת nftables, הוסיפו את הטבלה הזו ל-/etc/nftables.conf מתחת לטבלאות הקיימות שלכם:

table inet mangle {
  chain forward {
    type filter hook forward priority mangle; policy accept;
    tcp flags syn tcp option maxseg size set rt mtu
  }
}

טענו מחדש בעזרת sudo systemctl reload nftables. בשרת המבוסס על iptables, הפקודה המקבילה היא שורה אחת:

sudo iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

וודאו שהחוק נמצא בנתיב שבו עוברות החבילות. הריצו את sudo nft list table inet mangle או sudo iptables -t mangle -L FORWARD -n -v בזמן שלקוח פותח חיבורים חדשים, ועקבו אחר עליית המונה. מונה שנותר על אפס אומר שהחבילות אינן עוברות דרך ה-hook הזה, ולכן החוק אינו מבצע דבר.

כעת, למגבלות האמיתיות. ה-clamping מכסה TCP בלבד, והוא מכסה רק תעבורה מועברת (forwarded traffic). לכן, שירות שרץ על שרת ה-WireGuard עצמו לעולם לא עובר דרך ה-forward hook ולעולם לא יעבור clamping. זה משפיע גם על חיבורים שנפתחו לאחר טעינת החוק: סשנים קיימים שומרים על ה-MSS שעליו הסכימו מראש.

UDP נותר ללא שינוי, מכיוון של-UDP אין handshake שניתן לשכתב. רוב תעבורת ה-UDP שורדת בכל מקרה. QUIC, פרוטוקול התעבורה שמתחת ל-HTTP/3, בודק בעצמו את גודל החבילה השימושי ומתחיל קטן בכוונה. מה שלא שורד הוא UDP ששולח datagram גדול ומצפה שהוא יעבור, כמו תשובת DNSSEC (הרחבות אבטחת DNS) הגדולה מ-1400 בתים. שאילתות אלו מגיעות ל-timeout ומנסות שוב דרך TCP, מה שמגיע למשתמש כאתר איטי במקום כאתר שבור.

האם ה־CPU של ה־VPS שלי הוא צוואר הבקבוק?

WireGuard מבצע הצפנה באמצעות ChaCha20-Poly1305 ומחליף מפתחות באמצעות Curve25519. אין שימוש ב־AES בנתיב הנתונים, ולעובדה זו יש השלכה שאנשים רבים טועים לגביה: הוראות AES-NI ב־CPU שלכם אינן תורמות דבר ל־WireGuard. מארח שמצהיר על תמיכה ב־AES-NI אינו מציע לכם תכונת ביצועים עבור WireGuard. האלגוריתם ChaCha20 נבחר מכיוון שהוא מהיר במימוש תוכנה טהור, גם על מעבדים ללא כל האצה קריפטוגרפית.

זה לא אומר ש־WireGuard אינו צורך משאבים. ב־VPS עם 1 vCPU, ליבה אחת מטפלת גם בהצפנה וגם בפסיקות רשת (network interrupts), בנוסף לכל פעולה אחרת שהיישום שלכם מבצע.

בצעו מדידה בזמן העברת נתונים:

sudo apt install -y sysstat
mpstat -P ALL 1

קראו את שלושת הטורים. %soft הוא זמן ה־softirq, שבו מתבצע עיבוד החבילות ב־kernel. %steal הוא הזמן שה־hypervisor הקצה למישהו אחר. %idle הוא הזמן שנותר פנוי.

ערך %soft הקרוב ל־100 בליבה היחידה שלכם מעיד על כך שהשרת הגיע לתקרת עיבוד החבילות שלו, וזו מגבלה ממשית שתוספת ליבות תפתור. top מציג את ksoftirqd/0 בראש רשימת התהליכים באותו רגע, מה שמאשר את אותה המסקנה מזווית אחרת.

ערך %steal הגבוה מאחוזים בודדים אומר שהמגבלה אינה בשליטתכם, כיוון שהמארח עמוס מדי (oversubscribed) וה־vCPU שלכם ממתין לליבה פיזית. זה נפוץ בתוכניות השיתופיות הזולות ביותר ומשתנה לאורך היום. זמן גזול משכן רועש (Steal time) דורש בדיקה נפרדת, ושום ערך MTU לא יעזור במקרה זה.

גורם נוסף הוא המימוש שבו משתמש הלקוח. מודול ה־Linux kernel הוא הנתיב המהיר והוא מפזר את הצפנת ה־peer בין ליבות שונות. wireguard-go, המימוש במרחב המשתמש (userspace), איטי יותר, והוא מה שמשמש את לקוחות macOS ו־iOS, כיוון שפלטפורמות אלו אינן מאפשרות ליישום לטעון מודול kernel.

האם מדובר בנתיב או בקישור של העמית?

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

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

# on the client, outside the tunnel
iperf3 -c 203.0.113.10
# then through the tunnel
iperf3 -c 10.8.0.1

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

בדקו את שני הכיוונים, כיוון שחיבורים ביתיים הם בדרך כלל אסימטריים. iperf3 -c 10.8.0.1 -R הופך את כיוון הזרימה כך שהשרת הוא השולח. לקוח בקו 500/20 לעולם לא ידחוף יותר מ-20 Mbit של העלאה לתוך המנהרה, ושום שינוי בצד השרת לא ישנה זאת.

לאחר מכן, בצעו בדיקה עם זרמים (streams) מקבילים:

iperf3 -c 10.8.0.1 -P 4

אם ארבעה זרמים יחד מעבירים הרבה יותר מאשר זרם אחד, חיבור TCP בודד נכשל במילוי הנתיב. התפוקה של זרם בודד מוגבלת על ידי חלון הקבלה (receive window) חלקי זמן הלוך-חזור (RTT), לכן נתיב של 150 ms זקוק לחלון גדול כדי להעביר כמות משמעותית של נתונים. קראו את המגבלות שלכם:

sysctl net.ipv4.tcp_rmem net.ipv4.tcp_wmem

הערך השלישי בכל אחד מהם הוא המקסימום אליו Linux יבצע כוונון אוטומטי. אובדן חבילות (packet loss) מגביל גם הוא זרם בודד באופן קשיח, כיוון שאובדן הוא מה שבקרת הגודש של TCP מגיבה אליו, ונתיב ארוך הופך את ההתאוששות ליקרה. הריצו את mtr -rwc 100 203.0.113.10 מהלקוח למשך מאה מחזורים כדי לראות היכן מופיע אובדן לאורך הנתיב. אובדן שמתחיל בנתב אחד ונמשך עד לנתב האחרון הוא אובדן אמיתי. אובדן בנתב אמצעי שנעלם לאחר מכן מעיד על כך שהנתב מתעדף ICMP נמוך, ואין לו משמעות.

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

מה WireGuard אינו יכול לפתור

WireGuard הוא מנהרה (tunnel). הוא אינו יכול להיות מהיר יותר מהחוליה האיטית ביותר בנתיב שבו הוא משתמש, והוספתו תמיד הופכת את הנתיב לאיטי במעט.

הוא אינו מבצע דחיסה. אין לו מקבילה ל-comp-lzo של OpenVPN ואין תוכנית להוסיף אחת כזו, כיוון שדחיסה לפני הצפנה מדליפה מידע על הטקסט המקורי (plaintext). רוב נתוני ה-bulk כבר דחוסים, כך שבפועל אין לכך עלות. זהו אחד ההבדלים הממשיים שיש לשקול בעת השוואה בין WireGuard ל-OpenVPN, וזו בחירה תכנונית מכוונת.

מנהרה מלאה (full tunnel) משנה את המסלול שכל חבילת מידע (packet) עוברת. תעבורה שנהגה לעבור ממך ל-CDN (רשת להפצת תוכן) קרוב, עוברת כעת ממך ל-VPS שלך ומשם ל-CDN. אם ה-VPS נמצא ביבשת אחרת, כל בקשה משלמת את מחיר העיקוף הזה וזמן הלוך-חזור (round trip time) גדל בהתאם. שום ערך בתצורה לא יקצר זאת. העבירו את ה-VPS למיקום קרוב יותר, או השתמשו ב-split tunnel כך שרק התעבורה שזקוקה ל-VPN תעבור בדרך הארוכה. ההחלטה איזו תעבורה תעבור לאן נקבעת במלואה על ידי AllowedIPs, ו-ניתוב מפתחות הצפנה (cryptokey routing) מסביר כיצד החלטה זו מתקבלת.

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

PersistentKeepalive אינו משפיע על תפוקת הנתונים (throughput). הוא קיים כדי לשמור על מיפוי NAT פתוח, כך שהשרת יוכל להגיע ללקוח שנמצא מאחורי נתב ביתי. הורדת הערך מתחת ל-25 שניות רק מוסיפה חבילות מידע ולא פותרת דבר.

בצע מדידות לפי הסדר הבא

  1. שחזרו את הבעיה וציינו אם מדובר בקיפאון (hang) או בהאטה אחידה. קיפאון מצביע על בעיית MTU. האטה אחידה אינה מצביעה על כך.
  2. בצעו bisect באמצעות ping -M do מהלקוח לכתובת הציבורית של השרת, ורשמו את ה-MTU של הנתיב.
  3. החסירו 80, הגדירו את ה-MTU הזה ב-wg0 בשני הקצוות, ובדקו שוב את ההעברה שנכשלה.
  4. הוסיפו MSS clamping בשרת אם הוא מעביר תעבורה עבור עמיתים (peers).
  5. הריצו את mpstat -P ALL 1 במהלך העברה וקראו את %soft ואת %steal.
  6. הריצו את iperf3 מחוץ למנהרה ובתוכה, בשני הכיוונים, בזרם יחיד ועם -P 4.
  7. הריצו את mtr -rwc 100 אל השרת וחפשו אובדן חבילות שנמשך עד לדילוג (hop) האחרון.

שנו את תוכנית השרת רק לאחר ששלב 5 מצביע על כך שה-CPU הוא צוואר הבקבוק. שלבים 1 עד 4 אינם כרוכים בעלות ופותרים את רוב הדיווחים על מנהרה איטית.

FAQ

מדוע מנהרת WireGuard שלי מהירה בבדיקות ping אך איטית בהורדות?

הפער הזה הוא סימן מובהק לבעיית MTU. חבילות קטנות עוברות בכל קישור בנתיב, לכן ping וכניסת SSH עובדים היטב. העברת נתונים בנפח גדול שולחת מקטעים בגודל מלא; הגרסה המעוטפת שלהם גדולה ממה שחלק מהנתבים בנתיב מאפשרים. אם הנתב משליך את החבילות ללא החזרת הודעת ICMP, אובדן המידע לא מדווח וההעברה נתקעת. מצאו את ה-MTU של הנתיב באמצעות חצייה (bisection) עם ping -M do לכתובת הציבורית של השרת, החסירו 80 בתים עבור העטיפה, והגדירו את התוצאה כ-MTU של wg0 בשני הקצוות.

איזה MTU עלי להגדיר עבור WireGuard?

אין מספר אוניברסלי, וזו בדיוק הסיבה שברירת המחדל של 1420 נכשלת עבור חלק מהמשתמשים. 1420 הוא 1500 פחות 80 בתים של כותרת WireGuard, כותרת UDP וכותרת IPv6 חיצונית. אם הנתיב שלכם מעביר פחות מ-1500 בתים, דבר נפוץ בחיבורי PPPoE DSL ובכל מקום שבו התעבורה חוצה מנהרה נוספת, עליכם להשתמש בערך נמוך יותר. מדדו תחילה את ה-MTU של הנתיב, ולאחר מכן החסירו ממנו 80.

האם MSS clamping מחליף את הגדרת ה-MTU?

לא. Clamping משכתב את אפשרות ה-MSS ב-TCP handshake כך ששני הקצוות ישלחו מקטעים קטנים יותר, מה שמתקן את ה-TCP מבלי לגעת בממשק. ל-UDP אין handshake שניתן לשכתב, לכן הוא אינו מושפע. כמו כן, Clamping חל רק על תעבורה שהשרת מעביר (forwarding), כך ששירות שרץ על שרת ה-WireGuard עצמו לא יפיק מכך תועלת. השתמשו בשניהם: MTU תקין בממשק, ו-Clamping כדי לטפל בעמיתים (peers) שהתצורה שלהם אינה בשליטתכם.

האם תוכנית VPS מהירה יותר תאיץ את WireGuard?

רק אם המעבד הוא צוואר הבקבוק, ופקודה אחת תגלה לכם זאת. הריצו mpstat -P ALL 1 בזמן שהעברה מתבצעת. %soft קרוב ל-100 בליבה היחידה שלכם אומר שעיבוד החבילות הוא המגבלה, וליבות נוספות ישפרו את הביצועים. %steal גבוה מעיד על כך שהמארח (host) עמוס מדי, ולכן פתרון הוא מעבר לתוכנית אחרת או למארח אחר. אם שני המספרים נמוכים בזמן שהמנהרה עדיין איטית, המעבד אינו בשימוש ותוכנית גדולה יותר לא תשנה דבר.

מדוע ה-Mac שלי איטי יותר מלקוח ה-Linux באותה רשת?

לקוח ה-Linux משתמש במודול WireGuard ברמת ה-kernel, המעבד חבילות במרחב ה-kernel ומפזר את הצפנת העמית על פני ליבות המעבד. האפליקציות ל-macOS ול-iOS משתמשות ב-wireguard-go, מימוש במרחב המשתמש (userspace), מכיוון שפלטפורמות אלו אינן מאפשרות לאפליקציה לטעון מודול kernel. מרחב המשתמש מעתיק כל חבילה בין ה-kernel לאפליקציה, והעתקה זו גובה מחיר ברוחב הפס. הפער צפוי, ושום הגדרה בלקוח לא תסגור אותו.