কেন VPN-এর পিছনে থাকা Jenkins-এর বিরুদ্ধে GitHub webhook-গুলো টাইম আউট হয়
GitHub webhookগুলো ভেতরের দিকে পাঠায়, তাই Jenkins-কে রক্ষা করা VPN সেগুলো প্রত্যাখ্যান করে। ডেলিভারি বাইরের দিকে relay করুন, অথবা webhook-কে পোলিং করা agent দিয়ে বদলে দিন।
ডেলিভারি পৃষ্ঠাটি একটি টাইম আউট দেখায় এবং Jenkins কিছুই লগ করে না, যা এমন একটি সংযোগের চিহ্ন যেটি কখনোই পৌঁছায়নি। GitHub নিজের অবকাঠামো থেকে আপনার কনফিগার করা payload URL-এ একটি আউটবাউন্ড HTTP POST হিসেবে webhook পাঠায়। একটি VPN ঠিক এই ধরনের সংযোগ প্রত্যাখ্যান করে Jenkins-কে রক্ষা করে। দুই পক্ষের কোনোটিতেই কিছু ভাঙা নেই। সমস্যাটি অনুরোধের দিকেই।
ডেলিভারি আসলে কী করার চেষ্টা করে
GitHub payload URL-এর হোস্টনেম রিজলভ করে এবং পাবলিক ইন্টারনেট থেকে এটির সাথে সংযোগ করে। যদি সেই URL কোনো প্রাইভেট ঠিকানায়, বা এমন নামে নির্দেশ করে যা কেবল আপনার নেটওয়ার্কের ভেতরে রিজলভ হয়, তাহলে কোনো অনুরোধ পাঠানোর আগেই চেষ্টাটি ব্যর্থ হয়। যদি এটি এমন পাবলিক নামে নির্দেশ করে যা আপনার এজ বাদ দেয়, তাহলে চেষ্টাটি বরং টাইম আউট হয়।
এই পার্থক্যটি রোগনির্ণয়ের জন্য জরুরি। একটি DNS ব্যর্থতা এবং একটি ফিল্টার করা পোর্ট দুটিই এমন দেখায় যেন Jenkins-এর দিকে কিছুই ঘটেনি, এবং দুটিই GitHub-এ ভিন্ন কারণসহ একটি ব্যর্থ ডেলিভারি হিসেবে দেখা যায়। URL পরিবর্তনের আগে সেই কারণটি পড়ুন।
বাইরের দিকে ডায়াল করা একটি টানেল লিস্টেনার তৈরি করে না। মানুষ ঠিক এই অংশটিই ভিন্নভাবে কাজ করার আশা করে।
সংযোগের দিক ঠিক করার তিনটি উপায়
প্রতিটি সমাধান বদলে দেয় কে সংযোগটি শুরু করে, এবং কেবল তিনটি আকারই আছে।
| Approach | Who initiates | What you give up |
|---|---|---|
| Relay service | An outbound client inside the network | A third party sees every payload |
| Reverse tunnel or ingress | The public edge, into a controlled listener | An inbound surface you must secure |
| Runner or polling | The agent, outbound to GitHub | Instant delivery, replaced by a schedule |
পোলিং সবচেয়ে কম সুরুচিপূর্ণ এবং চালানো সবচেয়ে সহজ। একটি relay কোনো পোর্ট না খুলেই প্রায় তাৎক্ষণিক প্রতিক্রিয়া ধরে রাখে। যখন payload-এর গোপনীয়তা তৃতীয় পক্ষকে বাদ দেয়, তখন runner সাধারণত সঠিক উত্তর, কারণ কাজটি এমন মেশিনে চলতে পারে যা ইতিমধ্যেই নেটওয়ার্কের ভেতরে আছে।
যা আপনি চালাতে পারেন তার ভিত্তিতে বেছে নিন, যা আধুনিক শোনায় তার ভিত্তিতে নয়।
smee দিয়ে ডেলিভারি বাইরের দিকে relay করুন
relay পরিষেবায় একটি চ্যানেল তৈরি করুন এবং এর URL সংরক্ষণ করুন। নেটওয়ার্কের ভেতরে ক্লায়েন্ট ইনস্টল করুন এবং Jenkins যে পথটি প্রত্যাশা করে সেখানে ডেলিভারি পাঠান। রিপোজিটরি সেটিংসের payload URL-টি চ্যানেলের URL হয়ে যায়, কনটেন্ট টাইপ application/json-এ সেট করা থাকে।
sudo npm install --global smee-client
smee -u CHANNEL_URL --path /github-webhook/ --port 8080তিনটি বিবরণ ঠিক করে এটি কাজ করবে কি না। পথটি অবশ্যই GitHub ইভেন্টের জন্য Jenkins যা প্রত্যাশা করে তার সাথে মিলতে হবে, যা ডিফল্টভাবে /github-webhook/। Jenkins-কে অবশ্যই সেই পোর্টে শুনতে হবে যা আপনি ক্লায়েন্টকে দিয়েছেন। এবং জবে কনফিগার করা Jenkins URL-কে সেই পথের সাথে মিলতে হবে, নইলে ইভেন্টটি পৌঁছে তারপর বাদ পড়ে যায়।
শেষে স্ল্যাশের অমিল একটি 404 তৈরি করে যা ডেলিভারি ব্যর্থতার মতো পড়া যায়, কিন্তু তা নয়।
এটি চালানো যাতে সপ্তাহটা পার হয়
ফোরগ্রাউন্ড ক্লায়েন্ট টার্মিনালের সাথে মরে যায়, এবং webhookগুলো একদিন কাজ করে তারপর বন্ধ হয়ে যায়। এটিকে Restart=always সহ একটি unit দিন, Jenkins ব্যবহারকারী হিসেবে চালান, এবং প্রথম প্রকৃত ডেলিভারির পরে জার্নাল পড়ুন। শেষ ধাপটিই একটি কাজ করা relay-কে কনফিগার করা relay থেকে আলাদা করে।
[Unit]
Description=smee webhook relay
After=network.target
[Service]
Type=simple
Restart=always
RestartSec=2
User=jenkins
ExecStart=/usr/bin/smee -u CHANNEL_URL --path /github-webhook/ --port 8080
[Install]
WantedBy=multi-user.targetরিপ্লে বোতামের বদলে প্রকৃত push দিয়ে পরীক্ষা করুন। রিপ্লে relay-এর সংরক্ষিত payload চালায়, GitHub থেকে আপনার চ্যানেল পর্যন্ত পথ নয়, তাই লাইভ ডেলিভারি এখনো ব্যর্থ হলেও এটি পাস করতে পারে।
unit থামলে সতর্ক করুন। বন্ধ থাকা relay স্বভাবতই নীরব, এবং নীরবতাই হলো যা আপনি ইতিমধ্যে ডিবাগ করছেন।
relay কী দেখতে পারে, এবং কখন এটি ব্যবহার করবেন না
একটি relay payload সমাপ্ত করে, তাই এটি রিপোজিটরির নাম, commit ডেটা এবং ইভেন্ট যা কিছু বহন করে তা দেখে। চ্যানেলের URL-কে একটি পাবলিক এন্ডপয়েন্ট হিসেবে গণ্য করুন। Jenkins-এর সিক্রেট token কনফিগার করা রাখুন যাতে জাল ডেলিভারি প্রত্যাখ্যাত হয়, এবং Jenkins যে token ব্যবহার করে তার পরিধি প্রয়োজনীয় ন্যূনতমে সীমিত করুন।
যদি payload-এর গোপনীয়তা এটি বাদ দেয়, সেলফ-হোস্টেড runner বা প্রমাণিত রিভার্স টানেল হলো উত্তর।
relay এখন অবকাঠামো, এবং এটি যে বিল্ড ট্রিগার করে তার সমান পর্যালোচনার দাবিদার। চ্যানেল ফাঁস হলে এটি রোটেট করুন, এবং শেষবার কবে লাইভ ডেলিভারি যাচাই করেছেন সেই তারিখ লিখে রাখুন। সেই তারিখটি চ্যানেল URL-এর পাশে runbook-এ রাখুন। যে relay এক বছর ধরে কেউ পর্যালোচনা করেনি, সেটি এমন পাবলিক এন্ডপয়েন্ট যা কারও মালিকানাধীন নয়।