ব্লগে ফিরে যান
২৭ অক্টোবর, ২০২৫Sergei Solod5 মিনিট পড়া

আমার স্ট্যাটিক Next.js সাইটে প্রতিদিন হাজারো ভলনারেবিলিটি স্ক্যান আসে। Nginx প্রায় টেরই পায় না

লগে WordPress, PHP backdoor, .env আর .git/config খোঁজা probe-এর অভাব নেই। আমার static Next.js + Nginx সেটাপে এগুলোর বেশিরভাগই সস্তা miss ও 404 হয়ে শেষ হয়, আর পর্যবেক্ষণের সময় CPU load বদলায়নি। এই অভিজ্ঞতা static-site security সম্পর্কে আসলে কী বলে—এবং কী বলে না—সেটাই এখানে পরিষ্কার করছি।

নিরাপত্তাNext.jsNginxDevOpsস্ট্যাটিক হোস্টিংAttack Surface

প্রতিদিন আমার server log-এ হাজার হাজার automated vulnerability scan ধরা পড়ে। request-গুলো দেখতে বেশ ভয়ংকর:

  • /wp-admin/wp.php
  • /111.php
  • /code.php
  • /.git/config
  • /i.php
  • /admin
  • /api/.env
  • /kal.php

আমাকে অবাক করেছে সংখ্যাটা নয়, server-এর প্রতিক্রিয়া। এই traffic দেখার সময় CPU load-এ দৃশ্যমান কোনো পরিবর্তন দেখিনি।

এই observation সত্যি, কিন্তু আমার আগের ব্যাখ্যাটা অতিরিক্ত absolute ছিল। Static delivery কোনো জাদুর ঢাল নয়, আর 404-ও বিনা খরচে হয় না। আমার architecture-এর আসল সুবিধা আরও নির্দিষ্ট: opportunistic probe-এর বড় অংশ খুব কম কাজ করায়, কারণ public request path-এ পৌঁছানোর মতো server-side application logic প্রায় নেই।

এগুলো probe; compromise-এর প্রমাণ নয়

/wp-admin/wp.php বা /111.php দেখে প্রতিটি request-কে “exploit” বলা সহজ। কিন্তু সেটা technically precise নয়। আমি মূলত automated probing দেখি: bot পরিচিত filename আর endpoint ট্রাই করে দেখে কোনটা response দেয়।

কিছু path স্পষ্টভাবে WordPress বা PHP target করে। /.git/config আর /api/.env-এর মতো path ভুল করে প্রকাশিত configuration বা secret খোঁজে। /admin আরও generic; অনেক site-এ এটি বৈধ route-ও হতে পারে। সন্দেহজনক request আমাকে scanner কী খুঁজছে তা বলে, vulnerability সত্যিই আছে কিনা তা নয়।

আমার ক্ষেত্রে মূল বিষয় architecture: public site হলো Next.js দিয়ে pre-render করা static HTML, যা Nginx সরাসরি serve করে।

আমার stack-এ এই traffic কেন সস্তা

যে page-গুলোর কথা বলছি, প্রতিটি request-এর পেছনে PHP runtime বা database নেই। Nginx আগে থেকেই থাকা file serve করে। Scanner যদি /111.php চায় আর file না থাকে, কোনো PHP application boot হয় না, WordPress code execute হয় না, database query-ও চলে না। request miss হয়ে 404-এ শেষ হয়।

এতে cost model বদলে যায়। Dynamic application-এ একটি request routing, framework, authentication, rendering, database বা অন্য service পর্যন্ত যেতে পারে। আমার static path-এ moving parts অনেক কম। Nginx-কে তবুও connection accept করতে, HTTP process করতে, resource lookup করতে, log লিখতে এবং response পাঠাতে হয়; কিন্তু application-level কাজ কম।

সাইটে aggressive caching-ও ব্যবহার করি, যা স্বাভাবিক static delivery-তে সাহায্য করে। তবে random 404-এর প্রতিটা cache-এর কৃতিত্ব নয়। নতুন bogus URI 404 হওয়ার আগে স্বাভাবিক Nginx processing ও filesystem lookup পার করতে পারে।

গুরুত্বপূর্ণ সংশোধন: static মানেই “নিজে থেকেই secure” নয়

এই অংশটাই আমি এখন সবচেয়ে সতর্কভাবে বলব। Static architecture public request path থেকে অনেক server-side component সরিয়ে দেয়, কিন্তু security work সরায় না।

  • Exposed file static হলেও exposed-ই থাকে। .git, .env, backup বা কোনো secret public directory-তে পড়ে গেলে, configuration বাধা না দিলে Nginx HTML-এর মতোই সেটা serve করতে পারে।
  • Nginx, TLS, operating system ও network attack surface-এর অংশ। এগুলো patch ও সঠিকভাবে configure করা দরকার।
  • Client-side code-এও vulnerability থাকতে পারে। Static HTML JavaScript, browser-side auth logic বা third-party script-কে স্বয়ংক্রিয়ভাবে safe করে না।
  • Resource exhaustion সম্ভব। connection, bandwidth, TLS handshake, worker capacity, log I/O এবং disk space সীমিত। যথেষ্ট traffic static site-কেও চাপ দিতে পারে।

তাই সঠিক conclusion “এই request-গুলোর কোনো গুরুত্ব নেই” নয়; বরং এই architecture-এ অনেক application-specific probe-এর execute করার মতো কিছুই থাকে না।

“প্রতিদিন হাজারো scan” শোনার চেয়ে operational load কমও হতে পারে

Log background Internet noise-কে বড় করে দেখায়, কারণ প্রতিটি failed probe আলাদা line হিসেবে দেখা যায়। কিন্তু daily total একা operational impact বলে না। ২৪ ঘণ্টায় ছড়িয়ে থাকা কয়েক হাজার request আর অল্প সময়ের burst-এ একই সংখ্যা সম্পূর্ণ ভিন্ন ঘটনা।

CPU-ও শুধু একটি signal। আমার ক্ষেত্রে এটি স্থির ছিল, যা দেখায় যে observation-এর সময় এই traffic দৃশ্যমান compute pressure তৈরি করছিল না। কিন্তু অন্য resource-এর cost শূন্য ছিল—এমন প্রমাণ নয়। ভালো evaluation করতে হলে request rate, bandwidth, active connections, Nginx worker utilization, response latency, log volume এবং disk usage-ও দেখা উচিত।

এই noise দেখে আমি যা শিখেছি

আমার সবচেয়ে বড় শিক্ষা হলো architecture নিজেই automated attack-এর পুরো category-কে অপ্রাসঙ্গিক করে দিতে পারে, প্রতিটি scanner signature-এর জন্য আলাদা rule না লিখেও। Bot সারাদিন WordPress আর PHP backdoor খুঁজতে পারে; public path-এ যদি WordPress বা PHP না থাকে, ওই probe-গুলোর ব্যবহার করার মতো খুব কমই থাকে।

তবে “আমার stack-এর জন্য irrelevant” আর “harmless traffic” আমি এখন আর এক মনে করি না। আমার বর্তমান checklist:

  • Public request path থেকে কোন runtime ও service সত্যিই reachable তা জানি।
  • Secret, repository metadata, backup ও build artifact web root-এর বাইরে রাখি বা explicit block করি।
  • অন্য targeting বা impact-এর evidence না থাকলে repeated 404 probe-কে স্বাভাবিক Internet background noise হিসেবে দেখি।
  • শুধু CPU দেখে abusive traffic-কে free বলি না।
  • Application static হলেও Nginx, OS, TLS library ও dependency patch করি।

এই অভিজ্ঞতা যা প্রমাণ করে না

আমি controlled benchmark করিনি এবং DDoS simulate করিনি। প্রতিদিন হাজারো scanner request আসার সময় production log আর server load দেখেছি মাত্র। আমার setup নিয়ে practical conclusion করার জন্য তা যথেষ্ট, কিন্তু “static সব সময় জেতে” এমন universal rule প্রমাণ করে না।

আমি যেটা আত্মবিশ্বাসের সঙ্গে বলতে পারি তা আরও নির্দিষ্ট: Nginx-served Next.js static export-এ আমি যে scanner traffic দেখেছি তার বেশিরভাগ PHP runtime বা database-backed application-এ পৌঁছানোর বদলে low-cost file miss ও 404 হয়ে শেষ হয়েছে। পর্যবেক্ষণের সময় CPU load বদলায়নি।

এই resilience-টাই আমার কাছে গুরুত্বপূর্ণ। কম moving parts কোনো system-কে invulnerable করে না; শুধু random Internet noise-এর জন্য real application work-এ পরিণত হওয়ার জায়গা কমিয়ে দেয়।