عند تقييم بروتوكولات الأنفاق الآمنة، ينصب اهتمام مهندسي الشبكات عادةً على قوة خوارزميات التشفير وسلامة المصادقة. وتضمن الخوارزميات الحديثة مثل ChaCha20-Poly1305 (وفق المعيار RFC 8439) حماية محتويات الحزم ومنع تزويرها أثناء النقل المادي. بيد أن التشفير في حد ذاته لا يعالج ثغرة جوهرية ملازمة لطبيعة شبكات IP عديمة الاتصال: هجمات إعادة الإرسال (Replay Attacks).

لا يحتاج المهاجم الذي يتنصت على خطوط الاتصال إلى فك تشفير المفاتيح لإحداث أضرار بالغة. فمن خلال تسجيل حزم UDP الأصلية المشفرة وإعادة بثها في وقت لاحق، يستطيع تعطيل الجلسات النشطة، أو تكرار المعاملات المالية، أو استغلال ثغرات آلات الحالات في الطبقات العليا. وفضلاً عن ذلك، فإن إعادة استخدام القيمة الابتدائية (Nonce) في خوارزميات التشفير المتدفق مثل ChaCha20 لحزمتين مختلفتين بمفتاح واحد يُعد خطأً جسيماً يكشف تيار التشفير عبر عملية XOR بسيطة.

للقضاء التام على مخاطر إعادة الإرسال مع المحافظة على أعلى معدلات نقل البيانات عبر الشبكات المتقلبة، يعتمد بروتوكول WireGuard بنية دفاعية مستندة إلى RFC 6479. ومن خلال الجمع بين عدادات الإرسال ذات 64 بت والنافذة المنزلقة الرقمية القائمة على مصفوفة البتات، يضمن النظام حماية كاملة دون فقدان الحزم الناتجة عن اضطراب ترتيب الوصول.

+-----------------------------------------------------------------------------+
|                 آلية النافذة المنزلقة RFC 6479 في بروتوكول WIREGUARD        |
|                                                                             |
|      نطاق الإسقاط (قديم جداً)                النافذة النشطة (2048 بت)       |
|  ◄───────────────────────────┤──────────────────────────────────────────►   |
|   العداد < (T - 2048)        │               من (T - 2048) إلى T         │  |
|                              │                                           │  |
|  ... [الحزمة k] [الحزمة k+1] │ [بت 0] [بت 1] ... [بت i] ... [بت 2047]    │  |
|                              │   │       │           │           │       │  |
|                              │ الأقدم    │       الحزمة الحالية  │       │  |
|                              │ في النطاق │     (فحص وتحديد القيمة)│      │  |
|                              └───────────┴───────────┬───────────┴───────┘  |
|                                                      │                      |
|                                                      ▼                      |
|                                            إذا كان البت == 1: إسقاط (مكررة) |
|                                            إذا كان البت == 0: قبول وتعيين = 1|
|                                            إذا كان العداد > T: تقدم النافذة  |
+-----------------------------------------------------------------------------+

مخاطر تكرار Nonce وعدّاد النقل ذو 64 بت

تتطلب بنية ChaCha20-Poly1305 ثلاثة عناصر: مفتاحاً متناظراً بطول 256 بت، وحمولة البيانات الأصلية، وقيمة Nonce وحيدة. ويستخدم WireGuard عداداً متسلسلاً بطول 64 بت مباشرةً كقيمة Nonce لخوارزمية ChaCha20، مضافاً إليه وسم المصادقة Poly1305 بطول 16 بايتاً.

إن عدم تكرار Nonce شرط لا يقبل التهاون في علم التشفير. فلو قام المرسل بتشفير حزمتين مختلفتين بنفس الزوج من المفتاح وقيمة Nonce:

$$C_1 = P_1 \oplus Keystream(K, N)$$ $$C_2 = P_2 \oplus Keystream(K, N)$$

فسيتمكن أي طرف متنصت من إجراء عملية الجمع المنطقي XOR بين النصين المشفرين وإلغاء تيار المفتاح بالكامل:

$$C_1 \oplus C_2 = P_1 \oplus P_2$$

هذه النتيجة الرياضية تعرض البيانات للتحليل الإحصائي وتسهل تزوير وسوم Poly1305. لتفادي هذا الأمر، يزيد مرسل WireGuard قيمة العداد ذي 64 بت تصاعدياً بمقدار 1 مع كل حزمة جديدة، بدءاً من الصفر عند تأسيس الجلسة.

تستوعب مساحة 64 بت ما يفوق $1.8 \times 10^{19}$ حزمة، وهو رقم يستحيل استنفاذه في الاستخدام الاعتيادي. حتى مع ضخ البيانات بمعدل 100 جيجابت في الثانية، يستغرق استهلاك هذا المدى عقوداً متواصلة. ومع ذلك، يفرض بروتوكول Noise IKpsk2 تجديد المفاتيح المؤقتة كل بضع دقائق، ليعود العداد إلى الصفر مع مفتاح جلسة جديد تماماً.

تحديات اضطراب ترتيب الحزم عبر الإنترنت

مع أن الطرف المرسل يزيد العدادات بتسلسل دقيق ($0, 1, 2, 3, \dots$)، إلا أن بنية الإنترنت تتعامل مع حزم UDP باستقلالية تامة. وفي الواقع الميداني، تواجه الحزم:

  • التوجيه متعدد المسارات (ECMP): حيث توزع موجهات شبكات الاتصال الحزم على كابلات ألياف ضوئية ذات أزمنة انتقال متباينة.
  • تعدد طوابير المعالجة في بطاقات الشبكة (RSS): حيث تُقسم الحزم الواردة على أنوية المعالج المختلفة، مما يحدث تفاوتات طفيفة في التوقيت.
  • تقلبات الاتصال اللاسلكي والخلوي: مثل التبديل بين أبراج الجيل الخامس 5G أو تخزين حزم Wi-Fi المؤقت.

ونتيجة لذلك، تصل الحزم في كثير من الأحيان بغير ترتيب إرسالها:

$$\text{ترتيب الإرسال:} \quad [1, 2, 3, 4, 5, 6]$$ $$\text{ترتيب الوصول:} \quad [1, 3, 2, 5, 4, 6]$$

فلو اعتمد جهاز الاستقبال قاعدة صارمة تقضي برفض أي حزمة تحمل عداداً أقل من أكبر رقم وصله سابقاً، لأسقط الحزمة رقم 2 لمجرد أنها وصلت بعد الحزمة رقم 3. وإن إسقاط الحزم السليمة جراء تأخر طفيف يلحق ضرراً فادحاً بتدفقات بروتوكول TCP المنقولة داخل النفق.

وعندما يرصد TCP فقداناً في الحزم، يرسل إشعارات وصول مكررة، ويفعل آليات إعادة الإرسال السريع، ويخفض نافذة الازدحام إلى النصف، مما يؤدي إلى انهيار سرعة النقل. لذلك كان لزاماً على نظام الحماية أن يتقبل الحزم المنعكسة ترتيباً مع صد محاولات التكرار الخبيثة بدقة.

+-----------------------------------------------------------------------------+
|                     مصفوفة اتخاذ القرار للحزم الواردة                       |
+--------------------------+----------------------------+---------------------+
| عداد الحزمة الواردة ($C$)| الموقع بالنسبة للنافذة     | إجراء النواة        |
+--------------------------+----------------------------+---------------------+
| $C > T_{\text{القمة}}$    | يتجاوز أعلى رقم معروف      | تقديم حدود النافذة  |
|                          |                            | تعيين البت في الجدول|
+--------------------------+----------------------------+---------------------+
| $T_{\text{القمة}} - W \le$| يقع ضمن نطاق النافذة       | إذا كان البت 0: قبول|
| $C \le T_{\text{القمة}}$  | المنزلقة النشطة            | إذا كان البت 1: رفض |
+--------------------------+----------------------------+---------------------+
| $C < T_{\text{القمة}} - W$| خارج حدود النافذة الأدنى   | إسقاط فوري          |
|                          |                            | (حزمة منتهية/معادة) |
+--------------------------+----------------------------+---------------------+

خوارزمية RFC 6479: نافذة منزلقة دون إزاحة الذاكرة

لحل هذه المعضلة، استحدثت معايير IPsec الأولى (RFC 4303) نافذة منزلقة تستند إلى مصفوفة بتات بحجم 32 أو 64 بت. وعند وصول حزمة برقم أعلى، ينقل النظام كافة البتات في الذاكرة نحو اليسار.

ولكن في الشبكات فائقة السرعة التي تنقل ملايين الحزم في الثانية، فإن النقل المتكرر لمصفوفات كبيرة (مثل 1024 أو 2048 بت) داخل الذاكرة يستنزف دورات المعالج ويؤثر سلباً على الذاكرة المخبئية (Cache). لذا طبق WireGuard الخوارزمية المبتكرة الموضحة في وثيقة RFC 6479.

النموذج الحسابي والفهرسة الدائرية

بدلاً من تحريك البيانات في الذاكرة، تعتمد RFC 6479 على مصفوفة دائرية ثابتة من الكلمات البرمجية. وتبلغ سعة النافذة في WireGuard نحو $W = 2048$ بت، تتألف من 32 عنصراً من الأعداد الصحيحة بطول 64 بت ($32 \times 64 = 2048$ بت):

#define COUNTER_WINDOW_SIZE 2048
#define COUNTER_BITS_PER_WORD 64
#define COUNTER_WORDS (COUNTER_WINDOW_SIZE / COUNTER_BITS_PER_WORD) // 32 كلمة

struct noise_replay_counter {
    u64 counter;
    unsigned long backtrack[COUNTER_WORDS];
    spinlock_t lock;
};

وعند وصول حزمة برقم عداد $C$، يتحدد موقع الكلمة المسؤولة عبر عملية باقي القسمة:

$$\text{موقع الكلمة} = \left(\frac{C}{64}\right) \pmod{32}$$ $$\text{موقع البت} = C \pmod{64}$$

ونظراً لأن طول المصفوفة من مضاعفات الرقم 2، تتحول عملية القسمة إلى عملية منطقية AND سريعة للغاية:

unsigned long word_index = (counter / 64) & (COUNTER_WORDS - 1);
unsigned long bit_mask = 1UL << (counter & (COUNTER_BITS_PER_WORD - 1));

ديناميكية انزلاق النافذة

تُصنف الحزم الواردة وفق ثلاث حالات:

  1. ضمن النافذة النشطة ($T - W < C \le T$): يفحص النظام البت المحدد. فإذا كان يحمل القيمة 1، تُعد الحزمة مكررة وتُسقط فوراً. أما إذا كان 0، تُقبل الحزمة ويتحول البت إلى 1.
  2. أعلى من القمة ($C > T$): تسجل الحزمة أعلى رقم حتى الآن. يتعين تحريك النافذة للأمام. ويعمد النظام إلى تصفير الكلمات الوسيطة الواقعة بين القمة القديمة والجديدة، وتحديث القمة ($T = C$)، وتعيين البت المقابل.
  3. خارج النافذة من الأسفل ($C \le T - W$): تأخرت الحزمة بأكثر من 2048 موضعاً عن أعلى رقم مسجل. تسقط النواة الحزمة دون إهدار طاقة المعالجة في فك التشفير.

يحقق هذا النموذج تعقيداً زمنياً ثابتاً $O(1)$، ويتفادى حجز الذاكرة الديناميكي، مما يحفظ كفاءة المعالج.

توزيع المصفوفة الدائرية في الذاكرة (32 كلمة بطول 64 بت):
الكلمة 0     الكلمة 1     الكلمة 2           الكلمة 31
[64 بت]      [64 بت]      [64 بت]     ...    [64 بت]
    ▲
    │
    └── المؤشر الدائري يتحرك بسلاسة دون نقل البايتات في الذاكرة

المعالجة المتوازية والتزامن في المعالجات متعددة الأنوية

في بيئات الخوادم ذات الكثافة العالية، يتسبب فك تشفير ملايين حزم UDP على نواة واحدة في اختناق الأداء. وفي نواة لينكس، يوزع WireGuard أعباء التشفير بالتساوي على كافة الأنوية عبر آليات طوابير padata المتوازية.

مراحل المعالجة تتم بكفاءة:

  1. استقبال الحزم: يضع مشغل بطاقة الشبكة الحزم الواردة في طابور الاستقبال.
  2. فك التشفير المتوازي: يوزع WireGuard مهام ChaCha20-Poly1305 بالتوازي على الأنوية المستعدة، حيث تتحقق كل نواة من وسم المصادقة وتفك التشفير ذاتياً.
  3. التحقق التسلسلي من إعادة الإرسال: لتفادي تعارض الأنوية بسبب اختلاف أزمنة إتمام التشفير، يتم تحديث النافذة المنزلقة في مرحلة ختامية متسلسلة وخفيفة (wg_packet_consume_data_done) مدعومة بأقفال ذرية.

هذا الفصل بين الحسابات التشفيرية الثقيلة والتحقق المنطقي الخفيف يمنح WireGuard سرعات تمرير عالية جداً مع منع حدوث تعارض البيانات.

موازنة سعة النافذة مع تقلبات سرعة النقل

يمثل اختيار حجم 2048 بت توازناً هندسياً مدروساً بين استهلاك الذاكرة والقدرة على استيعاب تذبذب الشبكة:

  • النافذة الصغيرة (مثل 64 بت) تؤدي لإسقاط الحزم السليمة عند حدوث أي تأخير عابر في الوصلات السريعة.
  • النافذة الكبيرة للغاية (مثل 65536 بت) ترفع استهلاك الذاكرة لكل عميل، مما يقلل من كفاءة المعالج عند خدمة آلاف الجلسات في وقت واحد.

تغطي سعة 2048 بت لحزم MTU القياسية نحو 2.9 ميجابايت من البيانات قيد النقل، وهو ما يكفي لاستيعاب التفاوت الزمني في المسارات الدولية.

وفي منظومة VPNRice، يعتمد بروتوكول RiceGuard هذه الآليات المحكمة. وبالتكامل مع توجيه الطبقة الثالثة والتحسينات المشروحة في دليلنا حول بنية أنفاق UDP، يمنع RiceGuard تكرار البيانات ويحافظ على استقرار التدفق.

للاطلاع على أحدث إصدارات الحماية لكافة أجهزتك، تفضل بزيارة صفحة تحميل VPNRice.