ويب هوك GitHub لا يصل إلى Jenkins الخاص: إصلاح المسار
جلسة VPN على حاسوبك المحمول لا تمنح GitHub مسارًا إلى Jenkins. قارن بين نقطة نهاية واردة ومرحّل واستقصاء، ثم اختبر المسار الذي تسلكه الأحداث.
يمكنك فتح Jenkins عبر VPN ومع ذلك ترى GitHub يبلّغ عن فشل ويب هوك، لأن هذين اتصالان مختلفان لهما مالكَان مختلفان. المتصفح يسير في نفق تفاوض عليه حاسوبك؛ أما خدمة التسليم في GitHub فتبدأ من الإنترنت العام ولا تملك مسارًا إلى الشبكة الخاصة. الوصول إلى المستودع لا يغيّر ذلك، حتى لو كان Jenkins نفسه يجلب من المستودع ذاته دون مشكلة. اختر نقطة دخول أو مرحّلًا أو استقصاءً، ثم اختبر المسار الذي يسلكه الحدث فعليًا.
جلسة المتصفح تثبت اتجاهًا واحدًا فقط
اتصال VPN يجيب عن سؤال واحد: هل يستطيع هذا الحاسوب الوصول إلى المضيف الداخلي. أما تسليم ويب هوك فيسأل سؤالًا آخر: هل تستطيع خدمة خارجية فتح اتصال بذلك المضيف. جلب Jenkins للمستودع حركة صادرة ولا يقول شيئًا عن إمكانية الوصول الوارد. أبقِ الاتجاهين على سطرين منفصلين في مخططك، بما في ذلك الطرف الذي يبدأ كلًّا منهما.
اقرأ سجل التسليم قبل تغيير أي شيء. انتهاء المهلة وإعادة تعيين الاتصال وطلب مقبول لم يطابق أي مهمة لها ثلاثة مالكين مختلفين: الشبكة والوكيل وإعداد المُشغِّل.
الخيار أ: كشف نقطة نهاية ضيقة
إذا كانت المؤسسة تنشر بالفعل نقطة دخول معتمدة، فاكشف مسار ويب هوك بدلًا من لوحة التحكم. يعني ذلك عادةً قاعدة وكيل عكسي تقبل طلبات POST على عنوان URL للخطاف وتمرّرها إلى Jenkins بينما تبقى واجهة الإدارة غير قابلة للوصول من الخارج.
curl -sS -o /dev/null -w "%{http_code}\n" -X POST https://jenkins.example.com/github-webhook/شغّل ذلك الاختبار من شبكة بلا وصول VPN، لأن النجاح من داخل النفق لا يثبت شيئًا. يجب أن ترفض نقطة النهاية الطلبات التي تفتقر إلى السر المشترك، الذي يرسله GitHub في ترويسة توقيع، وأن تقبل فقط المسار والطريقة الوحيدين الذين نشرتهما. وحدة تحكم Jenkins العامة ليست إصلاحًا لويب هوك؛ بل حادث ينتظر الماسح التالي. أحكم نطاق القاعدة بما يكفي لتحتفظ بقية التطبيق بضوابط الوصول التي كانت لديها.
الخيار ب: عكس الاتجاه بمرحّل
حيث لا تُعتمد إمكانية الكشف الوارد، يستطيع عميل صغير داخل الشبكة إبقاء اتصال صادر بمرحّل مفتوحًا واستقبال الأحداث المحوّلة. يصبح المرحّل عندئذ جزءًا من مسار التسليم، فلم يعد يكفي أن تعمل مهمة البناء وحدها، بل صارت إتاحته ومصادقته بنفس القدر من الأهمية.
ssh -N -R 9000:localhost:8080 relay.example.netإرشادات Jenkins حول ويب هوك خلف الجدران النارية تصف هذا الشكل، ويستحق قراءتها قبل كتابة مُمرِّر مخصص. أنهِ TLS عند المرحّل، وتحقق من التوقيع قبل وصول الحدث إلى المهمة، وراقب الرابط الصادر، لأن النفق المنقطع يبدو تمامًا كحدث لم يُرسَل أبدًا. تأكد أيضًا من أن المرحّل يحفظ جسم الطلب بايتًا ببايت، لأن فحوص التوقيع تفشل مع JSON جرى تحليله وإعادة ترميزه في الطريق.
الخيار ج: استقصِ المستودع بدلًا من ذلك
الاستقصاء يقايض زمن الاستجابة بالبساطة ولا يحتاج إلى مسار وارد على الإطلاق. يمكن لـ Jenkins أن يستقصي وفق جدول، أو يمكن لمهمة صغيرة أن تستعلم من API وتبدأ بناءً عندما ترى مراجعة غير مألوفة.
curl -sS -u "$USER:$TOKEN" "https://api.github.com/repos/OWNER/REPO/commits?per_page=1"كل استقصاء يستهلك نداءات API ويضيف تأخيرًا بين الدفع والبناء، وهو ما يظهر في المستودعات المزدحمة وحدود المعدل المشتركة. يحتاج أيضًا إلى بيانات اعتماد مخزّنة حيثما يعمل المستقصي، فقيّد الرمز المميز بوصول قراءة فقط إلى المستودع وبدّله مثل أي سر آخر. اختر هذا عندما يكون حجم الأحداث منخفضًا أو عندما لا تُعتمد أي نقطة دخول أبدًا، واذكر ذلك في وصف المهمة حتى لا يتساءل أحد لاحقًا عن سبب تأخر البناء.
اقبل تسليمًا حقيقيًا، لا تحميل صفحة
أي خيار اخترت، فإن اختبار القبول هو حدث يرسله النظام المصدر، لا علامة تبويب متصفح تُفتح من حاسوب محمول ذي امتيازات. ادفع إيداعًا فارغًا إلى فرع مؤقت واقرأ رمز استجابة التسليم أو سجل المرحّل أو مخرجات مهمة الاستقصاء، بهذا الترتيب. استجابة 200 من نقطة النهاية دون بناء تعني أن مرشّح المُشغِّل خاطئ؛ وانتهاء المهلة يعني أن المسار ما زال مغلقًا. سجّل أي التصاميم الثلاثة قيد الاستخدام، وإلا فسيعيد الشخص التالي الذي يبحث عن الخطأ اختبار المتصفح ويصل إلى الطريق المسدود نفسه.
طبّق المنطق نفسه على عمليات ردّ الدفع والإشعارات الخارجية الأخرى: كل منها يحتاج مساره الخاص إلى التطبيق الخاص، حتى عندما يملك كل إنسان جلسة VPN بالفعل. مسار التسليم ينتمي إلى تصميم التطبيق، لا إلى حاشية في الشبكات.