SSD Nodes Learn 🎉 VPS از $5.50/ماه
راهنماها Matt Connorتوسط Matt Connor

جلوگیری از حملات بمباران اشتراک در فرم‌های ثبت‌نام

مهاجمان با ثبت ایمیل قربانی در صدها فرم، صندوق ورودی او را با پیام‌های تایید پر می‌کنند. با پیاده‌سازی تاییدیه دو مرحله‌ای و محدودیت نرخ ارسال، از سوءاستفاده جلوگیری کنید.

بمباران اشتراک (Subscription bombing) چیست؟

بمباران اشتراک نوعی حمله است که از فرم ثبت‌نام شما برای پر کردن صندوق ورودی (inbox) شخص دیگری استفاده می‌کند. مهاجم آدرس ایمیل یک قربانی را برمی‌دارد و آن را در بازهٔ زمانی کوتاهی در صدها یا هزاران فرم محافظت‌نشده وارد می‌کند. هر یک از آن سایت‌ها یک پیام خوش‌آمدگویی یا تأییدیه به آن آدرس ارسال می‌کنند. این پیام‌ها در کنار هم، ایمیل‌های ضروری که قربانی واقعاً باید بخواند را پنهان می‌کنند.

هدف این حمله، صاحب آن صندوق ورودی است. در حالی که صندوق ایمیل با تأییدیه‌های اشتراک پر می‌شود، مهاجم در حال خرج کردن پول از کارت بانکی آن شخص یا بازنشانی رمز عبور یکی از حساب‌های اوست. هشدار کلاهبرداری از طرف بانک همچنان ارسال می‌شود، اما این هشدار زیر دو هزار پیام دیگری که در همان ساعت دریافت شده‌اند دفن می‌شود و در نتیجه هیچ‌کس به‌موقع آن را نمی‌بیند.

سرور شما ابزاری است که این حمله با آن ساخته شده است. هیچ‌چیز در سیستم شما خراب نیست. هیچ‌کدام از حساب‌های شما هک نشده است. شخصی یک آدرس را در یک فرم عمومی وارد کرده و نرم‌افزار شما دقیقاً همان کاری را انجام داده که برای آن نوشته شده است: ارسال ایمیل به آن آدرس. همین موضوع تشخیص این حمله را دشوار می‌کند. هیچ نفوذی در لاگ‌های شما وجود ندارد، زیرا هیچ نفوذی صورت نگرفته است.

حمله از دیدگاه شما چگونه به نظر می‌رسد

این حمله به دو شکل رخ می‌دهد.

شکل پرسر و صدا، یک هجوم ناگهانی است. چند صد درخواست POST در عرض چند دقیقه به یک فرم خاص ارسال می‌شود. این درخواست‌ها از آدرس‌های IP مبدأ متعددی می‌آیند و حاوی آدرس‌هایی از دامنه‌هایی هستند که قبلاً هرگز به آن‌ها ایمیلی ارسال نکرده‌اید. اگر نگاهی به لاگ‌ها بیندازید، تشخیص این نوع حمله آسان است.

شکل بی‌سروصدا همان چیزی است که نادیده گرفته می‌شود. مهاجم فهرستی از هزاران فرم آسیب‌پذیر در اختیار دارد، بنابراین فرم شما فقط باید یک یا دو بار در ساعت در این حمله مشارکت کند. Jye Cusch حمله‌ای دقیقاً با همین ویژگی را توصیف کرده است که روی سایتی که مدیریت می‌کند رخ داده است: هیچ جهش ناگهانی در ترافیک وجود ندارد، فقط ثبت‌نام‌های مداومی در ساعاتی که با الگوی مخاطبان او همخوانی نداشت، دریافت شده است. یک فرم به‌تنهایی بی‌خطر به نظر می‌رسد، زیرا عملاً کار خاصی انجام نمی‌دهد. خسارت اصلی، مجموع تمام این موارد در کل فهرست فرم‌های مهاجم است.

هر دو شکل حمله پس از وقوع، یک نشانه مشترک دارند: هیچ اتفاقی نمی‌افتد. آدرس‌ها هرگز تأیید نمی‌شوند. آن‌ها هرگز پیامی را باز نمی‌کنند و هرگز روی لینکی کلیک نمی‌کنند. در یک فهرست با تأییدیه دو مرحله‌ای (Confirmed Opt-in)، این آدرس‌ها برای همیشه در وضعیت unconfirmed باقی می‌مانند و این انباشت، واضح‌ترین مدرکی است که به دست خواهید آورد.

کار را با شمارش تعداد درخواست‌های ارسالی در هر دقیقه در access log خود شروع کنید.

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

$4 در فرمت پیش‌فرض combined log، همان مهر زمانی (timestamp) داخل کروشه است، بنابراین این دستور تعداد درخواست‌ها را برای هر دقیقه چاپ می‌کند و بیشترین تعداد را در ابتدا قرار می‌دهد. فرمی که معمولاً چهار ثبت‌نام در روز دارد، اگر در یک دقیقه شصت ثبت‌نام نشان دهد، وضعیت عادی ندارد.

تأییدیه دو مرحله‌ای (Confirmed opt-in): مؤثرترین روش دفاعی

تأییدیه دو مرحله‌ای که معمولاً با نام double opt-in شناخته می‌شود، بدین معناست که یک آدرس ایمیل تا زمانی که فرد روی لینک موجود در پیام ارسالی به آن آدرس کلیک نکند، به عنوان مشترک ثبت نمی‌شود. با فعال‌سازی این قابلیت، هر آدرس ثبت‌شده دقیقاً و تنها یک پیام دریافت می‌کند. این آدرس هرگز به لیست نهایی اضافه نمی‌شود، بنابراین هیچ کمپین یا دنباله پیام‌های خوش‌آمدگویی برای آن ارسال نخواهد شد.

در listmonk، سرور خبرنامه خودمیزبان، این تنظیمات برای هر لیست به‌صورت جداگانه انجام می‌شود: یک لیست می‌تواند single opt-in یا double opt-in باشد. مستندات این ابزار تفاوت این دو را به‌صراحت بیان می‌کند. در یک لیست double opt-in، مشترکین «با کلیک بر روی ایمیل تأییدیه‌ای که دریافت می‌کنند، اشتراک خود را به‌طور صریح می‌پذیرند. تا آن زمان، آن‌ها هیچ پیام کمپینی دریافت نخواهند کرد.» یک مشترک در وضعیت unconfirmed قرار می‌گیرد، با کلیک بر روی لینک به وضعیت confirmed منتقل می‌شود و تنها مشترکین confirmed در یک لیست opt-in پیام‌های کمپین را دریافت می‌کنند.

در مورد دستاوردهای این روش صادق باشید. تأییدیه دو مرحله‌ای، مشارکت شما در ارسال هرزنامه را به صفر نمی‌رساند، بلکه آن را به یک پیام برای هر آدرس محدود می‌کند. قربانی همچنان همان یک پیام را دریافت می‌کند و دریافت یک پیام از هزار سایت مختلف، دقیقاً همان چیزی است که کل حمله را شکل می‌دهد. آنچه تأییدیه دو مرحله‌ای حذف می‌کند، تمام مراحل بعدی است: لیست شما تمیز باقی می‌ماند و شما هرگز پیام دومی را برای کسی که هرگز درخواست پیام اول را نداشته است، ارسال نخواهید کرد.

دو تنظیم دیگر نیز اهمیت دارند که اغلب فراموش می‌شوند. اول، محدود کردن ارسال مجدد ایمیل تأییدیه. اگر یک آدرس بتواند بارها ثبت شود و هر بار یک ایمیل تأییدیه دریافت کند، مهاجم نیازی به هزار فرم مختلف ندارد، زیرا فرم شما به تنهایی هزاران پیام ارسال خواهد کرد. آدرسی که در حال حاضر در وضعیت unconfirmed در آن لیست قرار دارد، نباید تا حداقل یک روز هیچ پیام دیگری دریافت کند. دوم، حذف ردیف‌های تأییدنشده طبق یک زمان‌بندی مشخص. آدرسی که در مدت 30 روز تأیید نشده است، یک مشترک در انتظار نیست. نگهداری آن فقط احتمال ارسال تصادفی پیام به آن در آینده را ایجاد می‌کند.

محدودسازی نرخ فرم ثبت‌نام در reverse proxy

محدودیت را به‌جای داخل برنامه، در مقابل آن قرار دهید. درخواستی که در proxy مسدود شود، هرگز اتصال دیتابیس باز نمی‌کند و هیچ نشست SMTP (پروتکل انتقال نامه ساده) را آغاز نمی‌نماید. محدودیت داخل برنامه پس از آن اجرا می‌شود که درخواست، هزینه یک worker process و یک کوئری را به شما تحمیل کرده است؛ در بسیاری از پشته‌های نرم‌افزاری، پیام پیش از اجرای هرگونه بررسی سوءاستفاده، در صف قرار می‌گیرد. محدودیت proxy همچنین در هنگام ارتقای برنامه باقی می‌ماند، زیرا در کدی که جایگزین می‌کنید قرار ندارد.

مثال زیر مربوط به nginx است. این ایده برای هر reverse proxy که در مقابل برنامه خود اجرا می‌کنید صادق است، هرچند نام دستورات متفاوت خواهد بود.

این کد را در بلوک http و در فایلی مانند /etc/nginx/conf.d/signup-limit.conf قرار دهید:

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 درخواستی را که کلید آن یک رشته خالی باشد نمی‌شمارد، بنابراین فقط درخواست‌های POST وارد zone می‌شوند. کاربری که صفحه ثبت‌نام را چندین بار بارگذاری می‌کند، هیچ هزینه‌ای (از سهمیه) نمی‌پردازد. بدون این map، کسی که صفحه را دو بار رفرش کند، پیش از آنکه چیزی ارسال کرده باشد، سهمیه خود را مصرف می‌کند.

$binary_remote_addr آدرس کلاینت به فرمت فشرده است، به همین دلیل یک zone با حجم 10 مگابایت می‌تواند تقریباً 160,000 آدرس را در خود جای دهد. rate=2r/m اجازه یک ارسال در هر 30 ثانیه را می‌دهد. limit_req_status 429 به‌جای کد پیش‌فرض 503 در nginx، کد HTTP 429 Too Many Requests را برمی‌گرداند که کد صحیح بوده و کتابخانه‌های کلاینت انتظار آن را دارند.

سپس در بلوک server برای سایت خود:

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 به کسی که دکمه را دوبار کلیک می‌کند اجازه عبور می‌دهد و درخواست چهارم را بلافاصله به‌جای قرار دادن در صف، رد می‌کند.

sudo nginx -t && sudo systemctl reload nginx

nginx -t باید configuration file /etc/nginx/nginx.conf test is successful را چاپ کند. اکنون فرم را پنج بار به‌سرعت ارسال کنید و لاگ خطا را زیر نظر بگیرید:

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

یک درخواست مسدودشده، یک خط می‌نویسد و این رشته‌ای است که باید به دنبال آن باشید:

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"

عدم مشاهده هیچ خطی به این معنی است که محدودیت اعمال نمی‌شود. دلیل معمول این است که limit_req در بلوک location قرار دارد که درخواست هرگز به آن نمی‌رسد؛ بنابراین با curl -si -X POST https://news.example.com/subscription/form چند بار پشت سر هم تست کنید و مطمئن شوید که 429 دریافت می‌کنید.

پیش از تکیه بر محدودیت بر اساس IP، دانستن دو نکته ضروری است.

پشت یک CDN یا proxy دیگر، $binary_remote_addr همان proxy است. همه بازدیدکنندگان در یک دسته قرار می‌گیرند، بنابراین چند ارسال اول در هر دقیقه، دسترسی بقیه را مسدود می‌کند. این مشکل را با ماژول real IP حل کنید: set_real_ip_from برای هر یک از محدوده‌های منتشرشده CDN خود (Cloudflare لیست خود را در cloudflare.com/ips قرار داده است) و real_ip_header CF-Connecting-IP. با خواندن $remote_addr در لاگ دسترسی و اطمینان از اینکه آدرس بازدیدکننده است و نه آدرس CDN شما، اصلاح را تأیید کنید.

IPv6 محدودیت بر اساس آدرس را ضعیف می‌کند. $binary_remote_addr کل /128 را در نظر می‌گیرد، در حالی که تخصیص IPv6 خانگی معمولاً /64 یا بزرگ‌تر است. این تعداد آدرس بسیار بیشتر از آن است که یک مهاجم بتواند از آن‌ها عبور کند و هر کدام سهمیه تمیز خود را دارند. یک zone دوم به‌عنوان سقف برای خود endpoint اضافه کنید که کلید آن یک مقدار ثابت باشد، تا فرم بدون توجه به تعداد آدرس‌های مبدأ در حال استفاده، نرخ کلی داشته باشد:

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

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

limit_req zone=signup_total burst=10 nodelay; را به همان location اضافه کنید. نرخ را بالاتر از شلوغ‌ترین ساعت واقعی خود با مقداری حاشیه تنظیم کنید. این یک کنترل کلی است: در طول حمله، ثبت‌نام‌های واقعی را نیز رد می‌کند. این معامله درستی است، زیرا جایگزین آن این است که سرور شما ایمیل ارسال کند.

چرا محدودیت بر اساس آدرس ایمیل نمی‌تواند در سطح پروکسی اعمال شود

آدرس ایمیل در بدنه درخواست POST ارسال می‌شود و nginx بدنه درخواست‌ها را پارس نمی‌کند. تمام متغیرهایی که limit_req_zone می‌تواند بر اساس آن‌ها کلیدسازی کند، از خط درخواست (request line)، هدرها یا اتصال (connection) استخراج می‌شوند. بنابراین، قانونی مانند «این آدرس می‌تواند حداکثر یک تأییدیه در روز دریافت کند» باید در اولین مؤلفه‌ای که بدنه را می‌خواند، یعنی همان برنامه شما، پیاده‌سازی شود.

برای دور زدن این محدودیت، آدرس را به رشته پرس‌وجو (query string) منتقل نکنید تا $arg_email در دسترس قرار گیرد. این کار باعث می‌شود آدرس هر مشترک به‌صورت متن ساده (cleartext) در لاگ دسترسی شما و هر ابزار انتقال لاگ (log shipper) در پایین‌دست ذخیره شود. در واقع شما یک محدودیت نرخ را با یک مشکل حریم خصوصی معاوضه خواهید کرد.

یک استثنای واقعی وجود دارد. ماژول JavaScript در nginx با نام njs می‌تواند بدنه درخواست را بخواند و متغیری از آن تنظیم کند که به شما اجازه می‌دهد یک کلید بر اساس آدرس در سطح پروکسی بسازید. این یک گزینه واقعی است، اما در عین حال کدی جدید در مسیر پردازش درخواست شما محسوب می‌شود. برای اکثر سایت‌ها، محدودیت بر اساس آدرس باید در کنار پایگاه‌داده‌ای قرار گیرد که از قبل می‌داند آیا این آدرس تأییدیه معلقی دارد یا خیر؛ در حالی که پروکسی محدودیت‌های بر اساس IP و endpoint را که در انجام آن‌ها مهارت دارد، مدیریت می‌کند.

از تکرار متن ارسالی در پیام خودداری کنید

هر رشته‌ای که توسط کاربر وارد شده است را از پیامی که ارسال می‌کنید، دور نگه دارید. دو دلیل مجزا برای این کار وجود دارد که هر دو در حملات واقعی مورد استفاده قرار گرفته‌اند.

اگر ایمیل تأیید شما، مخاطب را با نامی که از فرم گرفته شده خطاب قرار دهد، مهاجم می‌تواند متن مخرب خود را در فیلد نام وارد کند. سپس سرور شما آن متن را از طرف دامنه شما و با امضای کلید DKIM (DomainKeys Identified Mail) برای قربانی ارسال می‌کند. در این حالت، سایت شما به ابزاری برای سوءاستفاده دیگران تبدیل شده و سرویس‌دهنده مقصد، دامنه شما را به عنوان منبع تخلف شناسایی می‌کند.

دلیل دوم وخیم‌تر است. اگر هر فیلد ارسالی به‌صورت دستی در هدر ایمیل الحاق شود، یک کاراکتر خط جدید (newline) در آن فیلد به مهاجم اجازه می‌دهد هدرهای دلخواه خود، از جمله Bcc را اضافه کند. کتابخانه‌های مدرن ایمیل، کاراکترهای خط جدید در مقادیر هدر را رد می‌کنند، اما کدهایی که متن را از طریق اسکریپت‌های shell به sendmail ارسال می‌کنند، اغلب این کار را انجام نمی‌دهند.

یک پیام تأیید امن، شامل نام سایت شما، یک لینک و یک جمله توضیحی است. آدرس ایمیل تنها باید در جایی ظاهر شود که عامل انتقال ایمیل (MTA) به آن نیاز دارد، یعنی در هدر To. این مورد را آزمایش کنید: فرم را با فیلد نامی که حاوی یک خط جدید و یک لینک مشخص است ارسال کنید، سپس پیام خام دریافتی را با less بخوانید و مطمئن شوید که هیچ‌کدام از آن‌ها در پیام نهایی باقی نمانده‌اند.

در همین حین، صفحه موفقیت را طوری تنظیم کنید که برای همه آدرس‌ها پیام یکسانی نمایش دهد. صفحه‌ای که برای یک آدرس پیام «شما قبلاً عضو شده‌اید» و برای دیگری «صندوق ورودی خود را چک کنید» نمایش می‌دهد، فرم شما را به ابزاری برای بررسی عضویت در اختیار هر کسی قرار می‌دهد که لیستی از آدرس‌ها را برای تست در اختیار دارد.

از کدام بررسی ربات باید استفاده کنید؟

در انتخاب روش بررسی، همان‌قدر که به اثربخشی اهمیت می‌دهید، به دسترسی‌پذیری نیز توجه کنید. یک کپچای مبتنی بر انتخاب تصویر برای یک کاربر نابینا قابل حل نیست و جایگزین صوتی آن نیز برای افراد با شنوایی عادی دشوار است. بررسی‌ای که باعث شود یک کاربر واقعی از ثبت‌نام منصرف شود، در واقع هزینه‌ای است که به خودتان تحمیل کرده‌اید. چهار گزینه زیر را به ترتیب اولویت امتحان کنید.

اثبات کار (Proof of work) در مرورگر. مرورگر یک هش محاسبه می‌کند که سرور می‌تواند آن را با هزینه ناچیز تأیید کند و نیازی نیست کاربر چیزی را حل کند. listmonk این قابلیت را در بخش Settings و سپس Security با استفاده از ALTCHA ارائه می‌دهد که به هیچ سرویس شخص ثالثی نیاز ندارد. از اوت 2026، این روش توصیه خودِ listmonk نسبت به گزینه منسوخ‌شده hCaptcha است. هزینه این کار بر عهده کسی است که بیشترین درخواست را ارسال می‌کند، یعنی همان مهاجم.

بررسی مدیریت‌شده غیرتعاملی. سرویس Cloudflare Turnstile به اکثر بازدیدکنندگان چیزی نشان نمی‌دهد و تنها زمانی چالش ایجاد می‌کند که سیگنال‌های دریافتی مشکوک باشند. این روش مؤثر است، اما یک شخص ثالث را در مسیر ثبت‌نام شما قرار می‌دهد.

فیلد تله (Honeypot). یک ورودی متنی که کاربر هرگز آن را نمی‌بیند اما ربات‌های ساده‌لوح آن را پر می‌کنند. نامی برای آن انتخاب کنید که فرم شما در جای دیگری از آن استفاده نمی‌کند و مقادیر autocomplete="off"، tabindex="-1" و aria-hidden="true" را تنظیم کنید تا مدیر رمز عبور (password manager) آن را پر نکند و صفحه‌خوان (screen reader) آن را اعلام نکند. فیلدی با نام email2 یا address توسط مرورگر به‌صورت خودکار پر می‌شود و در نتیجه کاربران واقعی را رد خواهید کرد.

<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). هنگام رندر شدن صفحه، یک مُهر زمانی (timestamp) امضاشده در یک فیلد مخفی قرار دهید و ارسالی که کمتر از دو ثانیه بعد دریافت می‌شود را رد کنید. یک انسان نمی‌تواند فرم را بخواند و آدرس را با آن سرعت تایپ کند. مُهر زمانی را امضا کنید، در غیر این صورت ربات به‌سادگی یک مُهر زمانی قدیمی را ارسال می‌کند.

یک نکته که باید صرف‌نظر از انتخاب خود بررسی کنید: توکن باید فقط یک‌بار مصرف شود. اگر یک اسکریپت بتواند بررسی را یک‌بار حل کند و همان توکن را برای هزاران آدرس ارسال کند، آن بررسی فقط ثابت کرده است که یک مرورگر یک‌بار اجرا شده و نه چیزی بیشتر.

چگونه پیش از رسیدن گزارش سوءاستفاده (abuse report) متوجه موضوع شویم؟

شما می‌خواهید نمودارهای خودتان به شما هشدار دهند، نه واحد رسیدگی به سوءاستفاده (abuse desk) شرکت میزبان. دو مورد را زیر نظر بگیرید.

تعداد درخواست‌های ثبت‌نام را به تفکیک آدرس مبدأ در لاگ‌ها بشمارید:

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

سپس به fail2ban اجازه دهید همان خطوط limiting requests که nginx می‌نویسد را بخواند و متخلفان تکراری را مسدود کند. ابزار fail2ban یک فیلتر دقیقاً برای همین منظور ارائه می‌دهد. فایل /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

خروجی وضعیت، فیلتر jail و تعداد موارد شکست‌خورده و مسدودشده فعلی را فهرست می‌کند. مقدار Currently banned: 0 در یک روز عادی، صحیح است. اگر jail اصلاً نمایش داده نمی‌شود، یعنی fail2ban فایل را بارگذاری نکرده است و sudo fail2ban-client -d | grep nginx-limit-req پیکربندی‌ای که در واقعیت توسط آن تحلیل شده را نمایش می‌دهد. فیلتر پیش‌فرض با تمام زون‌های limit_req مطابقت دارد. آن را به زون ثبت‌نام خود محدود کنید؛ برای این کار ngx_limit_req_zones = signup را در بخش [Definition] از فایل /etc/fail2ban/filter.d/nginx-limit-req.local تنظیم نمایید. ساختار فایل jail و دستورات مسدودسازی در راهنمای fail2ban برای Ubuntu 24.04 به تفصیل بررسی شده‌اند.

سیگنال دوم یک نسبت است و به هیچ نرم‌افزار جدیدی نیاز ندارد: تعداد ثبت‌نام‌ها تقسیم بر تعداد تأییدیه‌ها. در یک لیست سالم، اکثر افرادی که آدرسی را ثبت می‌کنند روی لینک تأیید کلیک می‌کنند؛ معمولاً بیش از نیمی از آن‌ها. زمانی که این نسبت هم‌زمان با افزایش ثبت‌نام‌ها سقوط می‌کند، یعنی از سرویس شما سوءاستفاده می‌شود. تعداد مشترکین unconfirmed ایجادشده در ساعت گذشته را با تعداد مشترکین confirmed مقایسه کنید؛ این کار را طبق هر زمان‌بندی‌ای که برای گزارش‌گیری دارید، انجام دهید.

هزینه‌ای که می‌پردازید: اعتبار فرستنده و لیست‌های مسدودسازی

این بخشی است که یک مزاحمت ساده را به یک هزینه مالی تبدیل می‌کند.

لیست‌های آدرسی که برای بمباران ایمیلی استفاده می‌شوند، جمع‌آوری‌شده (harvested) هستند و این لیست‌ها حاوی تله‌های اسپم (spamtraps) می‌باشند؛ آدرس‌هایی که هرگز در هیچ کجا ثبت‌نام نکرده‌اند و صرفاً برای شناسایی فرستندگانی منتشر شده‌اند که بدون اجازه ایمیل ارسال می‌کنند. پیام تأیید شما به یکی از این آدرس‌ها می‌رسد. برخی از گردانندگان لیست‌های مسدودسازی (blocklist) تنها به همین یک مورد نیاز دارند.

گیرندگانی که هرگز درخواست دریافت پیام شما را نداشته‌اند، روی گزینه لغو اشتراک کلیک نمی‌کنند. آن‌ها روی "گزارش اسپم" کلیک می‌کنند. قوانین فرستندگان انبوه Google که از فوریه 2024 اجرایی شده است، به فرستندگان 5,000 پیام یا بیشتر در روز به Gmail دستور می‌دهد که نرخ گزارش اسپم در Postmaster Tools را زیر 0.3% نگه دارند. فرستندگان کوچک‌تر با این عدد سنجیده نمی‌شوند، اما همان سیگنال شکایت، تصمیمات فیلترینگ را تغذیه می‌کند که باعث می‌شود ایمیل‌های شما مستقیماً به پوشه اسپم برود. آدرس‌های جعلی موجود در این حملات نیز با خطای hard bounce مواجه می‌شوند و افزایش نرخ hard bounce، خود یک سیگنال منفی برای اعتبار شما نزد تمامی ارائه‌دهندگان بزرگ است.

اگر میل‌سرور اختصاصی خود را روی یک VPS با mailcow اجرا می‌کنید، قرار گرفتن در لیست سیاه مستقیماً به IP و دامنه شما آسیب می‌زند. خروج از لیست سیاه نزد اپراتورهایی مانند Spamhaus مستلزم پر کردن فرم و انتظار است؛ در حالی که منتظر هستید، ایمیل‌های مربوط به فاکتورها و بازنشانی رمز عبور شما نیز به دست کاربران نمی‌رسد. اگر از طریق یک ارائه‌دهنده اشتراکی ایمیل ارسال می‌کنید، انتظار داشته باشید که آن‌ها ابتدا حساب شما را مسدود کنند و سپس توضیحات شما را بخوانند، زیرا ترافیک شما ریسکی برای سایر فرستندگان روی آن IP محسوب می‌شود.

در مقایسه با این هزینه‌ها، کار لازم بسیار ناچیز است. همین امروز قابلیت confirmed opt-in را فعال کنید، چرا که تنها یک تنظیم برای هر لیست است. سپس محدودیت نرخ (rate limit) پروکسی را اضافه کنید، زیرا تنها شامل یک فایل و یک بار reload است. پیاده‌سازی بررسی ربات (bot check) و سیستم هشداردهی می‌تواند در طول همین هفته انجام شود.

FAQ

آیا تایید دو مرحله‌ای (double opt-in) جلوی بمباران اشتراک را می‌گیرد؟

این کار از آلوده شدن لیست شما جلوگیری می‌کند و تعداد پیام‌های ارسالی برای هر آدرس ثبت‌شده را به یک عدد محدود می‌سازد که بزرگ‌ترین بهبود ممکن برای شماست. این روش مانع پر شدن صندوق ورودی قربانی نمی‌شود، زیرا حمله حاصل مجموع یک پیام از هزاران سایت مختلف است. این قابلیت را با محدودیت نرخ (rate limit) بر اساس IP در پروکسی خود و محدودیت در ارسال مجدد تاییدیه ترکیب کنید تا ثبت یک آدرس برای بار دوم، منجر به ارسال پیام دوم نشود.

چگونه یک حمله بمباران را از یک روز خوب با ثبت‌نام‌های واقعی تشخیص دهم؟

به اتفاقاتی که پس از ثبت‌نام رخ می‌دهد دقت کنید. ثبت‌نام‌های واقعی تایید می‌شوند و معمولاً این کار را در عرض چند ساعت انجام می‌دهند. حمله بمباران مجموعه‌ای از آدرس‌ها را بر جای می‌گذارد که هرگز تایید نمی‌شوند، باز نمی‌شوند و روی آن‌ها کلیک نمی‌شود. زمان‌بندی ثبت‌نام‌ها نیز غیرعادی است: بسیاری از آدرس‌های مبدأ که قبلاً ندیده‌اید، دامنه‌های گیرنده‌ای که معمولاً به آن‌ها ایمیل نمی‌فرستید، و زمان‌های ورود که به‌طور یکنواخت در کل روز پخش شده‌اند، به‌جای اینکه از ساعات بیداری مخاطبان شما پیروی کنند.

آیا باید آدرس‌هایی که ثبت شده‌اند را حذف کنم؟

بله. رکوردهای تاییدنشده‌ای که بیش از حدود 30 روز از عمرشان می‌گذرد را حذف کنید و این کار را به‌صورت زمان‌بندی‌شده انجام دهید، نه دستی. هرگز برای آن آدرس‌ها هیچ پیام دیگری، از جمله عذرخواهی یا پیام "آیا این شما بودید؟" ارسال نکنید، زیرا این یک پیام ناخواسته دوم برای کسی است که قبلاً زیر انبوهی از پیام‌ها دفن شده است. اگر هر یک از آن آدرس‌ها تلهٔ اسپم (spamtrap) باشند، ارسال پیام بعدی همان تاییدی است که اپراتور لیست سیاه منتظر آن است.

آیا محدودیت نرخ (rate limiting) باعث رد شدن مشترکین واقعی می‌شود؟

محدودیت یک ثبت‌نام در هر 30 ثانیه با امکان جهش (burst) تا 3 مورد، برای شخصی که یک بار فرم را پر می‌کند نامحسوس است. این محدودیت زمانی محسوس می‌شود که افراد واقعی زیادی از یک آدرس مشترک استفاده کنند، مانند یک دفتر کار پشت یک گیت‌وی NAT (ترجمه آدرس شبکه)، یا زمانی که پروکسی شما به جای آدرس بازدیدکننده، آدرس CDN شما را می‌بیند. پیش از اعمال هرگونه محدودیت، $remote_addr را در لاگ دسترسی خود بخوانید و سقف نهایی را بالاتر از شلوغ‌ترین ساعت واقعی خود نگه دارید.

IP ارسال‌کننده من پس از یک حمله در لیست سیاه قرار گرفته است. اولین قدم چیست؟

پیش از هر درخواستی، ارسال از آن IP را متوقف کنید. صف کمپین را متوقف کنید، فرم را اصلاح کنید و آدرس‌های تاییدنشده را حذف کنید، زیرا حذف از لیست سیاه و سپس ادامه همان ترافیک، باعث می‌شود سریع‌تر از بار اول دوباره در لیست سیاه قرار بگیرید. سپس بررسی کنید در کدام لیست قرار دارید، زیرا اکثر اپراتورها یک صفحه جستجو بر اساس آدرس IP شما دارند؛ سپس فرآیند حذف آن‌ها را دنبال کنید. انتظار داشته باشید که این انتظار چند روز طول بکشد و از آن زمان برای تایید اینکه رکورد SPF (چارچوب سیاست فرستنده) و امضای DKIM شما همچنان معتبر هستند، استفاده کنید.

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