SSD Nodes Learn 🎉 VPS $5.50/মাস থেকে
নির্দেশিকা Matt Connorদ্বারা Matt Connor

Signup form-এ subscription bombing বন্ধ করার উপায়

Subscription bombing-এ একজন ভুক্তভোগীর address শত শত signup form-এ জমা হয়। Confirmed opt-in ও rate limit ব্যবহার করলে আপনার server একটিও mail পাঠাবে না।

সাবস্ক্রিপশন বোম্বিং কী?

সাবস্ক্রিপশন বোম্বিং এমন একটি আক্রমণ, যেখানে আপনার signup form ব্যবহার করে অন্য কারও inbox অপ্রয়োজনীয় বার্তায় ভরিয়ে দেওয়া হয়। আক্রমণকারী একজন ভুক্তভোগীর email address নিয়ে অল্প সময়ের মধ্যে শত শত বা হাজার হাজার সুরক্ষাহীন form-এ সেটি জমা দেয়। প্রতিটি site ওই address-এ welcome message অথবা confirmation message পাঠায়। সব বার্তা মিলে ভুক্তভোগীর প্রকৃতপক্ষে পড়া দরকার এমন mail আড়াল করে ফেলে।

লক্ষ্য হলো ওই inbox-এর মালিক ব্যক্তি। inbox-টি subscription confirmation-এ ভরে যাওয়ার সময় আক্রমণকারী সেই ব্যক্তির card ব্যবহার করে অর্থ খরচ করছে অথবা তার কোনো account-এর password reset করছে। ব্যাংকের fraud alert-ও তখন আসে। কিন্তু একই ঘণ্টায় আসা আরও দুই হাজার বার্তার নিচে সেটি চাপা পড়ে যায়, ফলে সময়মতো কেউ তা দেখতে পায় না।

আপনার server-ই এই আক্রমণের কাজে ব্যবহৃত tool। আপনার system-এ কোনো কিছু নষ্ট হয়নি। আপনার কোনো account compromised হয়নি। কেউ একটি public form-এ একটি address লিখেছে, আর আপনার software যেভাবে কাজ করার জন্য তৈরি, সেভাবেই কাজ করেছে: সেটি ওই address-এ mail পাঠিয়েছে। এই কারণেই বিষয়টি শনাক্ত করা কঠিন। আপনার log-এ কোনো intrusion নেই, কারণ কোনো intrusion ঘটেনি।

আপনার দিক থেকে আক্রমণটি কেমন দেখায়

এটি দুটি রূপের একটিতে আসে।

প্রথম রূপটি উচ্চমাত্রার। কয়েক মিনিটের মধ্যে কয়েক শ POST অনুরোধ একই ফর্মে আসে। এগুলো বিভিন্ন source IP address থেকে আসে এবং এমন domain-এর address বহন করে, যেগুলোতে আপনি আগে কখনও বার্তা পাঠাননি। আপনি খুঁজলে এই রূপটি সহজেই দেখা যায়।

দ্বিতীয় রূপটি নীরব। সাধারণত এটিই চোখ এড়িয়ে যায়। আক্রমণকারী হাজার হাজার দুর্বল ফর্মের একটি তালিকা ধরে রাখে। তাই আপনার ফর্ম থেকে প্রতি ঘণ্টায় মাত্র 1 বা 2টি submission এলেই যথেষ্ট। Jye Cusch ঠিক এই ধরনের একটি আক্রমণ বর্ণনা করেছেন, যে site তিনি পরিচালনা করেন সেখানে: traffic spike ছিল না; শুধু এমন সময়ে নিয়মিত signup আসছিল, যা তাঁর audience-এর সময়সূচির সঙ্গে মিলছিল না। একটি ফর্মকে নিরীহ মনে হয়, কারণ একটি ফর্ম প্রায় কিছুই করছে না। ক্ষতির পরিমাণ আক্রমণকারীর তালিকায় থাকা সব ফর্মের মোট ফল।

পরে দুটি রূপেরই একটি অভিন্ন চিহ্ন দেখা যায়: এরপর আর কিছু ঘটে না। address-গুলো কখনও confirm হয় না। কেউ message খোলে না এবং link-এ click করে না। confirmed opt-in তালিকায় এগুলো চিরকাল unconfirmed status-এ থাকে। এই জমে থাকা address-গুলোই আপনার হাতে থাকা সবচেয়ে স্পষ্ট প্রমাণ।

প্রথমে আপনার access log-এ প্রতি মিনিটে কতটি submission হয়েছে তা গুনুন।

sudo awk '/POST \/subscription\/form/ {print substr($4, 2, 17)}' \
  /var/log/nginx/access.log | uniq -c | sort -rn | head

ডিফল্ট combined log format-এ $4 হলো square bracket-এর মধ্যে থাকা timestamp। তাই এই command প্রতিটি মিনিটের count সর্বোচ্চ থেকে সর্বনিম্ন ক্রমে দেখায়। যে ফর্মে সাধারণত দিনে 4টি signup হয়, সেটিতে 1 মিনিটে 60টি signup দেখা গেলে সেটি স্বাভাবিক নয়।

নিশ্চিত opt-in: সবচেয়ে বেশি কার্যকর প্রতিরক্ষা

নিশ্চিত opt-in, যাকে সাধারণত double opt-in বলা হয়, এর অর্থ হলো কোনো ঠিকানায় পাঠানো বার্তার একটি লিংকে ব্যক্তি ক্লিক না করা পর্যন্ত সেই ঠিকানা subscriber হয় না। এটি চালু করলে জমা দেওয়া প্রতিটি ঠিকানা থেকে সর্বোচ্চ একটিই বার্তা পাঠানো হয়। ঠিকানাটি কখনো list-এ যোগ হয় না। তাই সেটি কোনো campaign বা welcome sequence পায় না।

self-hosted newsletter server listmonk-এ এটি প্রতি-list-এর একটি setting। একটি list হয় single opt-in, নয়তো double opt-in। documentation-এ পার্থক্যটি স্পষ্টভাবে বলা আছে। double opt-in list-এ subscriber-রা "তারা যে confirmation e-mail পায়, তাতে ক্লিক করে subscription স্পষ্টভাবে গ্রহণ করে। তার আগে তারা কোনো campaign message পায় না।" একজন subscriber unconfirmed অবস্থায় থাকে, ক্লিক করার পর confirmed অবস্থায় যায়, এবং opt-in list-এ শুধু confirmed subscriber-ই campaign mail পায়।

এটি আপনাকে বাস্তবে কী সুবিধা দেয়, সে বিষয়ে সৎ থাকুন। নিশ্চিত opt-in আপনার অবদানকে শূন্যে নামায় না। এটি প্রতি ঠিকানায় আপনার অবদানকে একটি বার্তায় সীমাবদ্ধ করে। ভুক্তভোগী সেই বার্তাটি তবুও পান, এবং এক হাজার site থেকে একটি করে বার্তাই পুরো আক্রমণ তৈরি করতে পারে। নিশ্চিত opt-in যা বন্ধ করে, তা হলো পরের সব বার্তা: আপনার list পরিষ্কার থাকে, এবং প্রথম বার্তাটিই চাননি এমন কাউকে আপনি আর দ্বিতীয় বার্তা পাঠান না।

আরও দুটি setting গুরুত্বপূর্ণ, এবং দুটিই সহজে ভুলে যাওয়া যায়। প্রথমত, confirmation পুনরায় পাঠানোর সংখ্যা সীমাবদ্ধ করুন। একই ঠিকানা আবার জমা দিলে যদি প্রতিবার আরেকটি confirmation email পাঠানো যায়, তাহলে আক্রমণকারীর এক হাজার form-এর প্রয়োজন হয় না। আপনার form একাই এক হাজার বার্তা পাঠাবে। কোনো list-এ ইতিমধ্যে unconfirmed অবস্থায় থাকা ঠিকানায় অন্তত এক দিন আর কিছু পাঠানো উচিত নয়। দ্বিতীয়ত, নির্দিষ্ট সময়সূচি অনুযায়ী unconfirmed row মুছে দিন। ত্রিশ দিনের মধ্যে যে ঠিকানা confirm করেনি, সেটি pending subscriber নয়। সেটি রেখে দিলে পরে ভুল করে কোনো বার্তা পাঠানোর সম্ভাবনাই শুধু তৈরি হয়।

Reverse proxy-তে signup form-এর rate limit নির্ধারণ করুন

Limit-টি application-এর ভেতরে না দিয়ে তার সামনে বসান। Proxy-তে আটকে যাওয়া request কখনো database connection খোলে না এবং SMTP (simple mail transfer protocol) conversation শুরু করে না। Application-এর ভেতরের limit কার্যকর হওয়ার আগেই request একটি worker process এবং একটি query ব্যবহার করে ফেলে। অনেক stack-এ abuse check চলার আগেই message queue-তে যোগ হয়। Application upgrade করলেও proxy limit কার্যকর থাকে, কারণ এটি প্রতিস্থাপন করা code-এর মধ্যে থাকে না।

নিচের উদাহরণটি nginx-এর জন্য। আপনার app-এর সামনে যে reverse proxy চালান, directive-এর নাম ভিন্ন হলেও ধারণাটি একই।

http block-এ এটি যোগ করুন। যেমন, /etc/nginx/conf.d/signup-limit.conf-এর মতো একটি file-এ:

map $request_method $signup_key {
    POST    $binary_remote_addr;
    default "";
}

limit_req_zone $signup_key zone=signup:10m rate=2r/m;
limit_req_status 429;
limit_req_log_level warn;

map বাস্তব কাজটি করে। nginx এমন request গণনা করে না যার key একটি empty string। তাই শুধু POST request-গুলো zone-এ প্রবেশ করে। কেউ signup page কয়েকবার load করলেও কোনো quota খরচ হয় না। এই map না থাকলে page দুবার refresh করা ব্যক্তি form submit করার আগেই নিজের budget শেষ করে ফেলত।

$binary_remote_addr হলো packed form-এ client address। তাই 10 megabyte zone-এ প্রায় 160,000টি address রাখা যায়। rate=2r/m প্রতি ত্রিশ সেকেন্ডে একটি submission অনুমোদন করে। limit_req_status 429 nginx-এর default 503-এর পরিবর্তে HTTP 429 Too Many Requests ফেরত দেয়। এটিই সঠিক status code এবং client library-ও এটি প্রত্যাশা করে।

এরপর আপনার site-এর server block-এ:

location = /subscription/form {
    limit_req zone=signup burst=3 nodelay;
    proxy_pass http://127.0.0.1:9000;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

burst=3 nodelay button-এ double-click করা ব্যক্তিকে request পাঠাতে দেয় এবং চতুর্থ request-টি queue-তে না রেখে সঙ্গে সঙ্গে reject করে।

sudo nginx -t && sudo systemctl reload nginx

nginx -t-এর output হিসেবে configuration file /etc/nginx/nginx.conf test is successful দেখানো উচিত। এবার form-টি দ্রুত পাঁচবার submit করুন এবং error log monitor করুন:

sudo tail -f /var/log/nginx/error.log

Blocked request একটি line লিখবে। আপনি এই string-টিই খুঁজছেন:

2026/08/13 09:14:22 [warn] 812#812: *4412 limiting requests, excess: 3.400 by zone "signup", client: 203.0.113.10, server: news.example.com, request: "POST /subscription/form HTTP/1.1", host: "news.example.com"

একটিও line না থাকলে limit প্রয়োগ হচ্ছে না। সাধারণ কারণ হলো limit_req এমন একটি location block-এর মধ্যে আছে, যেখানে request কখনো পৌঁছায় না। তাই পরপর কয়েকবার curl -si -X POST https://news.example.com/subscription/form চালিয়ে নিশ্চিত করুন যে আপনি একটি 429 পাচ্ছেন।

Per-IP limit-এর ওপর নির্ভর করার আগে দুটি সমস্যার কথা মনে রাখুন।

CDN বা অন্য proxy-এর পেছনে থাকলে $binary_remote_addr হলো সেই proxy। ফলে সব visitor একই bucket-এ পড়ে। তাই প্রতি মিনিটের প্রথম কয়েকটি submission-এর পর অন্য সবাই block হয়ে যায়। এটি ঠিক করতে real IP module ব্যবহার করুন: আপনার CDN প্রকাশিত প্রতিটি range-এর জন্য set_real_ip_from ব্যবহার করুন। Cloudflare-এর range cloudflare.com/ips-এ দেওয়া আছে। এরপর real_ip_header CF-Connecting-IP যোগ করুন। Access log-এ $remote_addr পড়ে পরিবর্তনটি যাচাই করুন এবং নিশ্চিত করুন যে সেখানে CDN-এর address নয়, visitor-এর address দেখা যাচ্ছে।

IPv6 per-address limit-কে দুর্বল করে। $binary_remote_addr সম্পূর্ণ /128 address ধরে রাখে। Residential IPv6 allocation সাধারণত /64 বা তার চেয়ে বড় হয়। এটি attacker-এর ব্যবহারের জন্য অনেক বেশি address দেয়, এবং প্রতিটির নিজস্ব সম্পূর্ণ budget থাকে। Endpoint-টির ওপর ceiling হিসেবে একটি দ্বিতীয় zone যোগ করুন। এটি একটি constant-এর ভিত্তিতে key হবে, যাতে যত source address-ই ব্যবহৃত হোক, form-এর মোট rate সীমাবদ্ধ থাকে:

map $request_method $signup_total_key {
    POST    "signup";
    default "";
}

limit_req_zone $signup_total_key zone=signup_total:1m rate=30r/m;

একই location-এ limit_req zone=signup_total burst=10 nodelay; যোগ করুন। পর্যাপ্ত margin রেখে আপনার সবচেয়ে ব্যস্ত বাস্তব hour-এর চেয়ে বেশি rate নির্ধারণ করুন। এটি একটি blunt control। Attack চলাকালে এটি বৈধ signup-ও block করবে। এটিই সঠিক trade-off, কারণ বিকল্প হলে আপনার server-কে mail পাঠাতে হবে।

প্রতি ঠিকানার সীমা proxy স্তরে রাখা যায় না কেন

ইমেইল ঠিকানাটি POST body-এর ভেতরে আসে, আর nginx request body parse করে না। limit_req_zone যে variable-গুলোর ওপর ভিত্তি করে key তৈরি করতে পারে, সেগুলো request line, header বা connection থেকে আসে। তাই “এই ঠিকানা প্রতিদিন সর্বোচ্চ একটি confirmation পেতে পারবে”—এমন rule-কে request body পড়ে এমন প্রথম component-এ রাখতে হবে। সেটি হলো আপনার application।

ঠিকানাটি query string-এ সরিয়ে $arg_email available করার চেষ্টা করবেন না। এতে প্রতিটি subscriber-এর ঠিকানা আপনার access log-এ cleartext হিসেবে লেখা হবে, এবং তার পরের যেকোনো log shipper-এও চলে যাবে। আপনি rate limit-এর বদলে একটি privacy সমস্যা তৈরি করবেন।

একটি বাস্তব ব্যতিক্রম আছে। nginx JavaScript module, njs, request body পড়ে সেখান থেকে একটি variable set করতে পারে। এর মাধ্যমে proxy স্তরে প্রতি-ঠিকানার key তৈরি করা সম্ভব। এটি কার্যকর একটি option, তবে এতে আপনার request path-এ নতুন code যুক্ত হয়। অধিকাংশ site-এর ক্ষেত্রে প্রতি-ঠিকানার সীমা সেই database-এর কাছেই থাকা উচিত, যেটি ইতিমধ্যে জানে এই ঠিকানার জন্য pending confirmation আছে কি না। অন্যদিকে proxy প্রতি-IP এবং প্রতি-endpoint limit পরিচালনা করবে, যে কাজের জন্য এটি উপযুক্ত।

জমা দেওয়া টেক্সট বার্তায় পুনরায় লিখবেন না

আক্রমণকারী সরবরাহ করতে পারে এমন কোনো string আপনার পাঠানো বার্তায় রাখবেন না। এর দুটি পৃথক কারণ রয়েছে, এবং বাস্তবে দুটিই ব্যবহার করা হয়েছে।

আপনার confirmation email-এ form থেকে নেওয়া নাম ব্যবহার করে পাঠককে সম্ভাষণ করলে আক্রমণকারী name field-এ নিজের message লিখতে পারে। এরপর আপনার server সেই text-টি আপনার domain থেকে, আপনার DKIM (DomainKeys Identified Mail) key দিয়ে signed করে victim-এর কাছে পাঠায়। আপনার site অন্যের abuse ছড়ানোর delivery service-এ পরিণত হয়, এবং receiving provider বার্তাটিতে আপনার domain দেখতে পায়।

দ্বিতীয় কারণটি আরও গুরুতর। কোনো submitted field হাতে mail header-এর সঙ্গে concatenate করা হলে, সেই field-এর একটি newline character আক্রমণকারীর পছন্দমতো header যোগ করতে পারে, যার মধ্যে Bcc-ও থাকতে পারে। আধুনিক mail library-গুলো header value-তে newline প্রত্যাখ্যান করে। কিন্তু shell script থেকে text pipe করে sendmail-এ পাঠানো code প্রায়ই তা করে না।

নিরাপদ confirmation message-এ আপনার site-এর নাম, একটি link এবং একটি বাক্যে explanation থাকা উচিত। Address-টি শুধু সেই জায়গায় থাকবে যেখানে mail transfer agent-এর প্রয়োজন, অর্থাৎ To header-এ। এটি পরীক্ষা করতে name field-এ newline এবং একটি স্পষ্ট link দিয়ে form submit করুন। এরপর less দিয়ে পাওয়া raw message পড়ে দেখুন, কোনোটিই সেখানে রয়ে গেছে কি না।

এই সুযোগে success page-টিও সব address-এর জন্য একই বার্তা দেখায় কি না নিশ্চিত করুন। একটি address-এর জন্য "আপনি ইতিমধ্যে subscribed" এবং অন্যটির জন্য "আপনার inbox পরীক্ষা করুন" দেখালে, address-এর তালিকা হাতে থাকা যে কেউ আপনার form-কে membership checker হিসেবে ব্যবহার করতে পারবে।

কোন bot check ব্যবহার করবেন?

কার্যকারিতার পাশাপাশি accessibility-কে সমান গুরুত্ব দিয়ে নির্বাচন করুন। ছবির অংশ বাছাই করতে হয় এমন captcha অন্ধ ব্যবহারকারী সমাধান করতে পারেন না। সাধারণ শ্রবণক্ষমতার ব্যবহারকারীদের জন্যও audio fallback কঠিন হতে পারে। কোনো বৈধ ব্যবহারকারীর signup বাধাগ্রস্ত করে এমন check একই সঙ্গে একটি defence এবং একটি খরচ। চেষ্টা করার ক্রমে চারটি option নিচে দেওয়া হলো।

ব্রাউজারে proof of work। ব্রাউজার এমন একটি hash গণনা করে যা server কম খরচে যাচাই করতে পারে। ব্যবহারকারীকে কিছু সমাধান করতে হয় না। listmonk-এ এটি Settings, তারপর Security-এর অধীনে ALTCHA ব্যবহার করে চালু করা যায়। এর জন্য third-party service দরকার হয় না। August 2026 অনুযায়ী, deprecated hCaptcha option-এর পরিবর্তে এটি listmonk-এর নিজস্ব সুপারিশ। সবচেয়ে বেশি submission যে করে, খরচটি তার ওপরই পড়ে। সেটি হলো attacker।

Managed non-interactive check। Cloudflare Turnstile অধিকাংশ visitor-কে কিছুই দেখায় না। এর signal খারাপ মনে হলেই কেবল challenge দেখায়। এটি কার্যকর, তবে signup path-এর মধ্যে একটি third party যুক্ত হয়।

একটি honeypot field। এটি এমন একটি text input যা ব্যবহারকারী দেখেন না, কিন্তু সাধারণ bot এতে মান বসিয়ে দেয়। আপনার form-এ অন্য কোথাও ব্যবহৃত হয় না এমন একটি name দিন। এরপর autocomplete="off", tabindex="-1" এবং aria-hidden="true" সেট করুন, যাতে password manager এতে মান না বসায় এবং screen reader এটি ঘোষণা না করে। email2 বা address নামের field ব্রাউজার autofill করে দিতে পারে। তখন আপনি বৈধ ব্যবহারকারীদের প্রত্যাখ্যান করবেন।

<div style="position:absolute; left:-9999px;" aria-hidden="true">
  <label for="hp_ref">Leave this field empty</label>
  <input type="text" id="hp_ref" name="hp_ref" autocomplete="off" tabindex="-1">
</div>

Time-to-submit check। Page render হওয়ার সময় একটি hidden field-এ signed timestamp বসান। এরপর দুই সেকেন্ডের কম সময় পরে আসা submission প্রত্যাখ্যান করুন। একজন মানুষ form পড়ে এত দ্রুত address টাইপ করতে পারেন না। Timestamp-এ signature দিন। তা না হলে bot সহজেই পুরোনো timestamp পাঠাবে।

আপনি যে option-ই বেছে নিন, একটি বিষয় যাচাই করুন: token একবারই ব্যবহার করা যাবে। কোনো script যদি একবার check সমাধান করে সেই token এক হাজার address-এর বিরুদ্ধে replay করতে পারে, তাহলে check কেবল প্রমাণ করেছে যে একটি browser একবার চলেছিল। এর বেশি কিছু নয়।

অপব্যবহারের রিপোর্ট আসার আগেই কীভাবে বুঝবেন?

আপনার নিজের graph-ই আপনাকে জানাবে। Hosting provider-এর abuse desk-এর ওপর নির্ভর করবেন না। দুটি বিষয় monitor করুন।

Log জুড়ে প্রতিটি source address থেকে আসা submission-এর সংখ্যা গণনা করুন:

sudo awk '/POST \/subscription\/form/ {print $1}' /var/log/nginx/access.log \
  | sort | uniq -c | sort -rn | head -20

এরপর fail2ban-কে nginx ইতিমধ্যে লিখে রাখা একই limiting requests line পড়তে দিন এবং বারবার অনুরোধ পাঠানো source-গুলো ban করুন। fail2ban-এ এই কাজের জন্য নির্দিষ্ট filter রয়েছে। /etc/fail2ban/jail.d/nginx-limit-req.local তৈরি করুন:

[nginx-limit-req]
enabled  = true
filter   = nginx-limit-req
port     = http,https
logpath  = /var/log/nginx/error.log
findtime = 600
maxretry = 10
bantime  = 3600
sudo systemctl reload fail2ban
sudo fail2ban-client status nginx-limit-req

Status output-এ jail-এর filter এবং বর্তমানে failed ও banned count দেখা যায়। শান্ত দিনে Currently banned: 0 থাকা স্বাভাবিক। Jail একেবারেই দেখা না গেলে fail2ban file-টি load করেনি। সে ক্ষেত্রে sudo fail2ban-client -d | grep nginx-limit-req চালিয়ে এটি আসলে যে configuration parse করেছে তা দেখুন। সরবরাহ করা filter-টি প্রতিটি limit_req zone-এর সঙ্গে match করে। ngx_limit_req_zones = signup সেট করে এটিকে আপনার signup zone-এ সীমাবদ্ধ করুন। এটি /etc/fail2ban/filter.d/nginx-limit-req.local-এর [Definition] section-এ করতে হবে। Jail file-এর বিন্যাস এবং ban command সম্পর্কে Ubuntu 24.04-এর fail2ban guide-এ আরও বিস্তারিত আলোচনা রয়েছে।

দ্বিতীয় signal হলো একটি ratio। এর জন্য নতুন software প্রয়োজন নেই: submission-এর সংখ্যা confirmation-এর সংখ্যা দিয়ে ভাগ করুন। সুস্থ list-এ যারা address submit করেন, তাদের অধিকাংশই link-এ click করেন; সাধারণত অর্ধেকের অনেক বেশি মানুষ তা করেন। Submission বাড়ার সময় এই ratio দ্রুত কমে গেলে বুঝবেন, আপনার system অপব্যবহারের জন্য ব্যবহার করা হচ্ছে। আপনি যে schedule-এ report চালান, সেই schedule অনুযায়ী গত এক ঘণ্টায় তৈরি হওয়া unconfirmed subscriber-এর সংখ্যা এবং confirmed subscriber-এর সংখ্যা তুলনা করুন।

আপনার জন্য এর খরচ: প্রেরকের সুনাম এবং blocklist

এটাই সেই অংশ, যা একটি বিরক্তিকর ঘটনাকে সরাসরি খরচে পরিণত করে।

বোম্বিংয়ের জন্য ব্যবহৃত address list সাধারণত সংগৃহীত তালিকা থেকে নেওয়া হয়। এসব সংগৃহীত তালিকায় spamtrap থাকে: এমন address, যেগুলো কোথাও কোনো কিছুর জন্য কখনও নিবন্ধন করা হয়নি এবং অনুমতি ছাড়া mail পাঠানো প্রেরকদের শনাক্ত করার জন্যই প্রকাশ করা হয়েছে। আপনার confirmation message এমন একটি address-এ পৌঁছে যায়। কিছু blocklist operator-এর জন্য এটুকুই যথেষ্ট।

যারা আপনার message পাওয়ার অনুরোধ করেনি, তারা unsubscribe-এ click করে না। তারা "report spam"-এ click করে। February 2024 থেকে কার্যকর Google-এর bulk sender rules অনুযায়ী, Gmail-এ দিনে 5,000 বা তার বেশি message পাঠানো sender-দের Postmaster Tools-এ reported-spam rate 0.3%-এর নিচে রাখতে হবে। ছোট sender-দের এই সংখ্যার ভিত্তিতে মাপা হয় না, কিন্তু একই complaint signal filtering decision-এ ব্যবহৃত হয় এবং আপনার mail spam folder-এ পাঠিয়ে দিতে পারে। এই run-এ ব্যবহৃত ভুয়া address-গুলোও hard bounce করে, আর hard-bounce rate বাড়া প্রতিটি বড় provider-এর কাছে আলাদা reputation signal।

আপনি যদি VPS-এ mailcow ব্যবহার করে নিজের mail server চালান, তাহলে listing আপনার IP address এবং domain-এ যুক্ত হবে। Spamhaus-এর মতো কোনো operator-এর কাছ থেকে delisting করতে একটি form পূরণ করে অপেক্ষা করতে হয়। অপেক্ষার সময় আপনার invoice এবং password reset message-ও deliver হবে না। অন্যদিকে, shared provider-এর মাধ্যমে mail পাঠালে তারা আগে আপনার account suspend করবে এবং পরে আপনার ব্যাখ্যা পড়বে বলে ধরে নিন। কারণ আপনার traffic ওই IP-এর অন্য সব sender-এর জন্যও risk তৈরি করে।

এর তুলনায় কাজটি খুব ছোট। আজই confirmed opt-in চালু করুন, কারণ প্রতিটি list-এর জন্য এটি একটি setting। এরপর proxy rate limit যোগ করুন, কারণ এর জন্য একটি file এবং একটি reload যথেষ্ট। bot check এবং alerting এই সপ্তাহেই যোগ করা যাবে।

FAQ

ডাবল opt-in কি subscription bombing বন্ধ করে?

এটি আপনার list-এ অপ্রাসঙ্গিক address জমা হওয়া বন্ধ করে এবং আপনার পাঠানো প্রতিটি address-এর জন্য contribution সর্বোচ্চ একটি message-এ সীমাবদ্ধ রাখে। আপনার জন্য এটিই সবচেয়ে বড় একক উন্নতি। তবে এটি victim-এর inbox ভরে যাওয়া বন্ধ করে না, কারণ আক্রমণটি এক হাজার site থেকে আসা একটি করে message-এর সমষ্টি। এর সঙ্গে proxy-তে প্রতি-IP rate limit এবং confirmation resend-এর সর্বোচ্চ সীমা ব্যবহার করুন। এতে একই address দুবার submit করলেও দ্বিতীয় message তৈরি হবে না।

একটি ভালো দিনে প্রকৃত signup হওয়ার ঘটনা থেকে bombing run কীভাবে আলাদা করব?

Submission-এর পরে কী ঘটে তা দেখুন। প্রকৃত signup-গুলো confirm হয়, এবং সাধারণত কয়েক ঘণ্টার মধ্যেই confirm হয়। একটি bombing run এমন অনেক address রেখে যায় যেগুলো কখনো confirm, open বা click হয় না। Submission-এর ধরনেও অস্বাভাবিক cluster দেখা যায়: অনেক এমন source address, যা আপনি আগে কখনো দেখেননি; এমন recipient domain, যেখানে আপনি সাধারণত পাঠান না; এবং সারাদিন জুড়ে সমানভাবে ছড়ানো arrival time, আপনার audience-এর জেগে থাকার সময় অনুসরণ না করে।

Submit করা address-গুলো কি মুছে ফেলব?

হ্যাঁ। প্রায় thirty দিন ধরে unconfirmed থাকা record মুছে ফেলুন এবং এটি হাতে না করে schedule অনুযায়ী করুন। ওই address-গুলোতে আর কখনো কোনো message পাঠাবেন না, apology বা "was this you?" message-ও নয়। কারণ এতে এমন একজনকে দ্বিতীয় অনুরোধহীন message পাঠানো হবে, যিনি ইতিমধ্যে এই message-গুলোর চাপে পড়েছেন। ওই address-গুলোর কোনোটি spamtrap হলে follow-up message-ই blocklist operator-এর অপেক্ষা করা confirmation হয়ে দাঁড়াবে।

Rate limiting কি প্রকৃত subscriber-দের reject করবে?

প্রতি-IP প্রতি thirty সেকেন্ডে একটি submission এবং তিনটির burst limit form একবার পূরণ করা একজন ব্যবহারকারীর কাছে বোঝা যাবে না। তবে একই address ব্যবহার করে অনেক প্রকৃত ব্যক্তি থাকলে এটি বোঝা যাবে, যেমন একটি single NAT (network address translation) gateway-এর পেছনে থাকা office-এ; অথবা আপনার proxy visitor-এর address-এর বদলে CDN-এর address দেখতে পেলে। কোনো limit কঠোর করার আগে access log-এ $remote_addr পরীক্ষা করুন এবং endpoint-এর সর্বোচ্চ সীমা আপনার ব্যস্ততম প্রকৃত hour-এর চেয়ে বেশি রাখুন।

একটি run-এর পরে আমার sending IP blocklist-এ আছে। প্রথমে কী করব?

কোনো request করার আগে ওই IP থেকে sending বন্ধ করুন। Campaign queue pause করুন, form ঠিক করুন এবং unconfirmed address-গুলো মুছে ফেলুন। কারণ delisting-এর পরে একই ধরনের traffic আবার পাঠালে প্রথমবারের চেয়ে দ্রুত relisting হবে। এরপর কোন list-এ আপনার IP আছে তা খুঁজে বের করুন। অধিকাংশ operator আপনার IP address দিয়ে খোঁজার জন্য একটি lookup page দেয়। তাদের removal process অনুসরণ করুন। অপেক্ষার সময় কয়েক দিন হতে পারে। এই সময়ে আপনার SPF (sender policy framework) record এবং DKIM signing এখনও pass করছে কি না নিশ্চিত করুন।

#email#double-opt-in#rate-limiting#abuse#deliverability