صرف نظر و مشاهده محتوا

Odoo 19 Community: Web RBL – فهرست مسدودسازی برای ترافیک حمله به وب‌سایت‌های خودی

24 سپتامبر 2026 توسط
Odoo 19 Community: Web RBL – فهرست مسدودسازی برای ترافیک حمله به وب‌سایت‌های خودی

کد منبع: github.com/Alex0176/odoo-web-rbl — AGPL-3، آزادانه قابل استفاده.

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

این مطلب Web RBL را شرح می‌دهد، یک ماژول متن‌باز برای Odoo 19 Community که این ترافیک را شناسایی، امتیازدهی، ثبت و رد می‌کند — و فهرست مسدودسازی را به‌صورت فهرست RBL منتشر می‌کند، یعنی در قالبی که فایروال‌ها و Reverse Proxyها مستقیماً می‌خوانند. همه‌ی اعداد از عملیات واقعی می‌آیند.

ماژول چه می‌کند — نمای کلی قابلیت‌ها

عملکردچه می‌کندتحویل
تشخیص الگوکاوش‌ها را از روی مسیر و پسوند تشخیص می‌دهد: .env، .git، فایل‌های پیکربندی، کلیدهای ابری، دستورالعمل‌های ساخت CI/CD، WordPress، PHP، Path Traversal، مدیران پایگاه داده، GraphQL، اجرای فرمان از طریق /api/fs/exec و رابط‌های مشابهمسدود کردن
سه سطح برای هر الگومسدود کردن، شمارش یا گزارش — برای هر الگو بدون کد قابل تغییربرای هر الگو
آستانه‌هااین تعداد برخورد از یک الگوی واحد پیش از مسدودسازی؛ برای ورود ده10 برای ورود
دفاع در برابر ورودورودهای ناموفق از طریق فرم و XML-RPC/JSON-RPC، بررسی‌های ناموفق نشست، دسترسی به مدیر پایگاه داده — در پایگاه داده، نه در حافظه‌ی اصلیروشن
تشخیص ربات در ورودهر که پس از ده تلاش ناموفق پیام انتظار را نادیده بگیرد و همچنان در بزند، بلافاصله مسدود می‌شودمسدود کردن
تشخیص رفتارنشانی‌هایی که در پنج دقیقه بیست صفحه‌ی خطا و تقریباً هیچ صفحه‌ی موجود تولید می‌کنند — یعنی حدس می‌زنند به‌جای آن‌که بخوانندگزارش
امتیازدهی 0–100چقدر قطعی است که پشت نشانی یک مهاجم است؟ از شدت الگو، تعداد الگوهای متفاوت، روزهای مشکوک، دامنه‌های تحت تأثیر و تعداد برخوردها — با توضیح به زبان سادهروشن
مسدودسازی ورود بر اساس امتیازاز یک امتیاز قابل‌تنظیم به بالا ورود ممنوع می‌شود، وب‌سایت خواندنی می‌مانداز 40
سوءظن به اطلاعات دسترسی سرقت‌شدهورود موفق از یک نشانیِ مشکوک گزارش می‌شود و در صورت تمایل به‌صورت وظیفه واگذار می‌گردد — یک بار برای هر نشانی در هر روزروشن
فهرست‌های تهدیدگره‌های خروجی Tor، Spamhaus DROP، FireHOL Level 1 و blocklist.de از پیش پیکربندی شده‌اند؛ هر فهرست RBL دیگری را می‌توان با نشانی‌اش افزود، تطبیق روزانه، برای هر فهرست یک سطح جداگانهگزارش
بدون دسترسی به ورودسطح چهارم برای فهرست‌ها و کشورها: وب‌سایت قابل خواندن است، اما فرم ورود و رابط‌ها بسته‌اند — پاسخ مناسب برای Torگزینه
کشور مبدأکشور برای هر مورد و هر نشانی از طریق GeoLite2؛ ماژول پایگاه داده را با یک کلید مجوز رایگان خودش به‌روز نگه می‌داردنمایش
قوانین کشوریمسدودسازی، بدون دسترسی به ورود، گزارش یا صراحتاً آزاد — برای هر کشور، آگاهانه بدون مقدار پیش‌فرضهیچ
پیکربندی‌های نادرستQNAP، Synology، Exchange-Autodiscover، ActiveSync و WebDAV/CalDAV/CardDAV شناسایی می‌شوند، هرگز مسدود نمی‌شوند و همراه با یافته و دامنهٔ مربوط در یک فهرست کاری قرار می‌گیرندگزارش
یک تیکت برای هر نشانیاز یک یافته در صورت تمایل یک تیکت ساخته می‌شود — دقیقاً یکی برای هر نشانی؛ تیکت بسته‌شده دوباره باز می‌شود، نه اینکه تکراری شودخاموش
صفحه‌های الزامی و جمع‌آورندگانمسیر استانداردِ صفحهٔ اطلاعات قانونی (Impressum) همیشه در دسترس می‌ماند؛ آزمودن خودکار املاهای بیگانه شناسایی می‌شود و در صورت تمایل مسدود می‌گرددگزارش
فهرست مجازنشانی‌ها و شبکه‌هایی که هرگز مسدود نمی‌شوند؛ هر روز از فایروال (طرف‌های مقابل VPN) و از بازه‌های نشانیِ منتشرشدهٔ Googlebot و Bingbot پر می‌شودروشن
انتساب به مشتریموردی که از شبکهٔ یک مشتری بیاید به او نسبت داده می‌شود — از روی فهرست مجاز، نه با حدس دستیروشن
دامنه و شناسهٔ هر موردکدام وب‌سایت مورد درخواست قرار گرفته و با کدام User-Agent — هر دو در گزارش دسترسی غایب‌اندروشن
تحلیلنمودار و Pivot روی همهٔ موارد: بر حسب الگو، روز، دامنه، کشور، نشانیروشن
طعمهبه پروب‌ها پاسخ‌های ساختگی همراه با مقدار قناری داده می‌شود؛ هر کس بعداً آن را فراخوانی کند، آن‌ها را خوانده استخاموش
ارائهٔ RBLفهرست مسدودسازی به‌صورت فهرست ساده‌ٔ نشانی‌ها یا JSON در نشانیِ مخصوصِ محافظت‌شده با توکن — برای HAProxy، OPNsense و هر فایروالی که فهرست‌های URL را می‌خواندروشن

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

تحلیل Web RBL: موارد به تفکیک الگو در هفت روز

تحلیل: موارد به تفکیک الگو در هفت روز. بلندترین ستون، جست‌وجوی فایل‌های .env است.

فهرست‌های RBL: یک راه استاندارد برای ارائهٔ مسدودسازی‌ها

RBL مخفف Real-time Blackhole List است. این اصطلاح از دنیای ایمیل می‌آید، جایی که Spamhaus و دیگران از دهه 1990 فهرست‌هایی از نشانی‌های فرستندهٔ مخرب منتشر می‌کنند. اصل کار بسیار ساده است و درست به همین دلیل چنین فراگیر شده: در هر خط یک نشانی، قابل دریافت از طریق HTTP، با بارگذاری مجدد منظم. نه قالبی که اول باید تجزیه شود، نه رابطی که برایش ابزاری لازم باشد.

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

  • OPNsense و pfSense — URL Table Alias: بارگیری فهرست نشانی‌ها از طریق HTTP، استفاده به‌عنوان Alias در قوانین فایروال، به‌روزرسانی به‌صورت ساعتی یا روزانه
  • HAProxy — ACL-Dateien و Maps: src -f sperrliste.txt در یک قاعدهٔ http-request deny، قابل بارگذاری مجدد از طریق API زمان اجرا بدون راه‌اندازی مجدد
  • nginx — ماژول geo با فایل نشانی ضمیمه‌شده، یا دستورهای deny از یک فایل include تولیدشده
  • Fortinet FortiGate — External Block List یا Threat Feed: یک URL که فایروال از آن یک فهرست IP دریافت می‌کند و در سیاست‌ها به کار می‌برد
  • Palo Alto Networks — External Dynamic List (EDL): همان اصل، به‌عنوان یک نوع شیء جداگانه در سیاست‌های امنیتی
  • Check Point — Custom Intelligence Feeds و IP Block Lists از طریق یک URL
  • Cisco Secure Firewall (Firepower) — Security Intelligence Feeds با منابع فهرست اختصاصی
  • Sophos Firewall — Third-Party Threat Feeds: فهرست نشانی‌ها از یک URL به‌عنوان منبع قوانین مسدودسازی
  • Juniper SRX — Dynamic Address Entries از Feedها
  • MikroTik RouterOS — Address Lists، پرشده با اسکریپت و fetch از یک URL
  • CrowdSec — فهرست‌های اختصاصی به‌عنوان منبع برای Bouncerها روی هر سیستم پشتیبانی‌شده

Web RBL فهرست مسدودسازی‌اش را دقیقاً در همین قالب ارائه می‌کند. فایروال بسته‌ها را پیش از رسیدن به وب‌سرور دور می‌ریزد — و همراه با آن‌ها هر تلاش دیگر از همان نشانی را، مثلاً به سمت سرور ایمیل یا دروازهٔ VPN.

هر دو جهت، اما در جای درست

این مسیر برعکس هم کار می‌کند: در Web RBL می‌توان هر فهرست RBL دلخواهی را ثبت کرد — یک URL، یک سطح، تمام. گره‌های خروجی Tor، Spamhaus DROP، FireHOL و blocklist.de از پیش پیکربندی شده‌اند و فهرست‌های دیگر با سه کلیک اضافه می‌شوند. ماژول هر فهرست را به بازه‌های نشانی تقسیم می‌کند و هر درخواست را با آن می‌سنجد، در چند میکروثانیه.

با این حال: معقول‌تر آن است که فهرست‌های بیگانه را روی فایروالِ پیش از آن به کار ببرید. به سه دلیل. فایروال همهٔ سرویس‌ها را می‌بیند، نه فقط HTTP — نشانی‌ای که در فهرست Spamhaus است باید در سرور ایمیل و VPN هم ناکام بماند. فایروال در سطح بسته رد می‌کند، پیش از آنکه اصلاً اتصالی برقرار شود، و بدین ترتیب هیچ هزینه‌ای برای سرور برنامه ندارد. و فایروال جایی است که این فهرست‌ها به هر حال در آن نگهداری می‌شوند؛ نسخهٔ دوم در برنامه، جای دومی است که می‌تواند کهنه شود.

اما فهرست‌ها در ماژول به چه کار می‌آیند: برای کاری که فایروال از عهده‌اش برنمی‌آید. فایروال فرم ورود را نمی‌شناسد. Web RBL می‌تواند به یک نشانی از فهرست Tor دسترسی به ورود را ندهد و با این حال وب‌سایت را تحویل دهد — کسی که می‌خواهد گمنام بخواند، باید بتواند؛ کسی که می‌خواهد گمنام گذرواژه بیازماید، نه. و می‌تواند ورود موفق از یک نشانیِ فهرست‌شده را به‌عنوان مورد مشکوک گزارش کند. هر دو کار فهرست را در همان جایی می‌خواهند که ورود انجام می‌شود.

امتیازدهی به‌جای حدس و گمان

نشانی‌ای که یک بار /wp-login.php را درخواست کرده، با نشانی‌ای که در دو روز با پنج الگوی مختلف روی سه دامنه رفته است، یکی نیست. Web RBL این را به یک امتیاز از 0 تا 100 تبدیل می‌کند — از آنچه خودش دیده است، بدون سرویس بیگانه و بدون پرس‌وجو از بیرون.

مورد Web RBL با امتیاز 84 و دلیل آن

یک مورد: 99 رخداد، امتیاز 84، و دلیل آن به زبان ساده — سنگین‌ترین الگو، پنج الگوی جدی متفاوت، دو روز مشکوک، بیش از بیست رخداد.

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

فهرست مسدودسازی Web RBL، فیلترشده بر اساس امتیاز از 40 به بالا

فهرست مسدودسازی، فیلترشده بر اساس امتیاز از 40 به بالا: تعداد رخدادها، روزهای مشکوک، دامنه‌های درگیر و آخرین مسیر برای هر نشانی.

Web RBL از چه چیزی محافظت می‌کند — اثر حفاظتی به تفکیک

1. اطلاعات ورود کشف‌نشده می‌مانند

بزرگ‌ترین ردهٔ حملهٔ اندازه‌گیری‌شده دنبال حفره‌ای در Odoo نیست، بلکه دنبال رازهای به‌جامانده است. در طول هفده روز:

  • 57.721 درخواست برای فایل‌های .env — در آن‌ها گذرواژه‌های پایگاه داده، کلیدهای API و رازهای نشست قرار دارند
  • 5.535 درخواست برای فایل‌های پیکربندی
  • 4.388 درخواست برای اطلاعات دسترسی ابری: credentials.json، service-account.json، firebase-adminsdk.json، rclone.conf، .git-credentials
  • 2.811 درخواست برای پوشه‌های .git — هر کس یکی را بیابد، کد منبع کامل را همراه با تاریخچه بارگیری می‌کند
  • 1.907 درخواست برای دستورالعمل‌های ساخت مانند .github/workflows/deploy.yml یا .gitlab-ci.yml، که رجیستری‌ها و نام کلیدها در آن‌ها آمده است

آنچه تعیین‌کننده است، تعداد درخواست‌ها نیست، بلکه تعداد نشانی‌های متفاوت است: /credentials.json از 98 نشانی آمد، /.git-credentials از 92 نشانی. این یک اسکنر تکی نیست، بلکه یک ذخیرهٔ استاندارد است که در سراسر جهان همزمان اجرا می‌شود.

2. تلاش‌های ورود به هدر می‌روند — پایدار

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

Web RBL در همان نقاط وارد می‌شود، اما در پایگاه داده می‌نویسد. بنابراین:

  • وضعیت از هر راه‌اندازی مجدد جان به در می‌برد و در میان همهٔ فرایندهای کاری معتبر است
  • هر دو مسیر ثبت می‌شوند: فرم ورود /web/login و رابط‌های /xmlrpc/2/common و /jsonrpc
  • تلاش‌هایی هم ثبت می‌شوند که هرگز به بررسی گذرواژه نمی‌رسند — مثلاً ورودهای بدون نشانهٔ نشست معتبر
  • دسترسی ناموفق به مدیر پایگاه داده نیز شمرده می‌شود؛ این جدی‌ترین تلاش ورود است

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

اما کسی که با وجود پاسخ «لطفاً کمی صبر کنید» از سوی سرور همچنان در می‌زند، بی‌درنگ مسدود می‌شود. این پیام را انسان می‌خواند و صبر می‌کند؛ کسی که نادیده‌اش بگیرد، یک برنامه است. یک الگوی جداگانه با آستانهٔ صفر همین حالت را می‌گیرد و نمی‌تواند به همکاری آسیب بزند: به آنجا فقط کسی می‌رسد که پیش‌تر ده تلاش ناموفق پشت سر گذاشته و پس از آن ادامه می‌دهد.

3. حمله دیگر هزینه‌ای برای سرور ندارد

پروبی روی مسیری مانند /@fs/../../.env پیش از ماژول گران بود: Odoo صفحهٔ خطا را می‌جوید، رندرش می‌کند، هنگام ساختن نشانی روی بخش‌های نقطه‌ای می‌لغزد و در نتیجه روی صفحهٔ خطای صفحهٔ خطا هم شکست می‌خورد. دو ردیابی پشته برای هر پروب. در هفده روز 28.401 خطای از این دست اندازه‌گیری شد، به‌علاوهٔ 9.467 خطای پیامد.

Web RBL در ir.http._match وارد می‌شود، یعنی پیش از مسیریابی. پاسخ بدون قالب، بدون دسترسی به پایگاه داده فراتر از بررسی مسدودسازی و بدون خط گزارش داده می‌شود. بررسی در برابر فهرست مجاز، فهرست‌های تهدید و قوانین کشوری از حافظهٔ نهان و روی بازه‌های نشانیِ مرتب‌شده انجام می‌شود — چند میکروثانیه، حتی با بیش از سی هزار بازه.

4. فایروال مهاجم را پیش از رسیدن بیرون می‌اندازد

فهرست مسدودسازی به‌صورت فهرست RBL منتشر می‌شود که HAProxy و OPNsense مستقیماً آن را می‌خوانند. بدین ترتیب مهاجم اصلاً دیگر به وب‌سرور نمی‌رسد — و به هیچ سرویس دیگری روی همان میزبان هم نه. دسترسیِ یک‌بار شناخته‌شده به‌عنوان مخرب، به این ترتیب با اثر بازگشتی از کل ماشین محافظت می‌کند.

سه سطح: مسدودسازی، شمارش، گزارش

هر درخواستِ بی‌نتیجه حمله نیست. Web RBL به همین دلیل سه سطح را از هم تفکیک می‌کند و سطح را می‌توان برای هر الگو تغییر داد، بی‌آنکه به کد دست زد.

سطحدرخواستِ آغازگرپیامد برای نشانی
مسدودسازیرد می‌شود24 ساعت مسدود، پس از سه روز مشکوک به‌طور دائمی
شمارشعبور می‌کندفقط ثبت می‌شود، بدون مسدودسازی
گزارشعبور می‌کندبا متن یافته ثبت می‌شود، هرگز مسدود نمی‌شود

برای فهرست‌های تهدید و کشورها سطح چهارمی هم هست: بدون دسترسی به ورود. وب‌سایت قابل خواندن می‌ماند، فرم ورود و رابط‌ها بسته‌اند. این راه میانه است برای هر چه مشکوک است اما لزومی ندارد مخرب باشد — Tor، یک بازهٔ مرکز داده، کشوری بدون مشتری.

کدام حمله‌ها شناسایی می‌شوند

همهٔ الگوها در برابر ترافیک واقعی آزموده شده‌اند. تعداد نشانی‌های متفاوت آگاهانه در کنارش آمده است — نشان می‌دهد که آیا یک الگو یک اسکنر تکی را می‌گیرد یا یک روش رایج را.

رده حملهدرخواست‌هانشانی‌ها
برداشت .env57.721223
پروب‌های PHP12.237256
Path Traversal با هدف ارزشمند10.04664
فایل‌های پیکربندی5.535114
کلیدهای دسترسی ابری4.388152
پروب‌های WordPress3.366385
برداشت .git2.811255
شناسایی Odoo (مدیر پایگاه داده، پرس‌وجوی نسخه)2.500213
زنجیره‌های ابزار هوش مصنوعی و اجرای فرمان (/mcp, /api/fs/exec)2.45074
دستورالعمل‌های ساخت (CI/CD)1.90788
نقاط پایانی GraphQL1.87871

ردهٔ تازه‌تر قابل توجه است. /api/fs/exec 369 بار از 54 نشانی متفاوت درخواست شد — این دسترسی خواندنی نیست، بلکه تلاش برای اجرای فرمان است. چنین هدف‌هایی دو سال پیش وجود نداشتند؛ از رابط‌های ابزارهای تازهٔ هوش مصنوعی و صف‌های وظیفه می‌آیند. هر کس دفاعش را فقط روی WordPress و PHP تنظیم کند، چیزی از این نمی‌بیند. در امتیازدهی این رده به همین نسبت سنگین می‌شود.

فهرست‌های تهدید و کشور مبدأ

فهرست‌های تهدید Web RBL: Tor، Spamhaus DROP، FireHOL، blocklist.de

چهار فهرست، 32.851 بازهٔ نشانی، همه روی «فقط گزارش». هر فهرست دیگر یک نشانی و یک سطح است.

یک فهرست بیگانه ادعایی است که شخص دیگری مطرح کرده، به دلایلی که ما نمی‌دانیم، دربارهٔ ترافیکی که هرگز ندیده‌ایم. ممکن است نادرست باشد، کهنه باشد یا برای هدفی دیگر تهیه شده باشد: blocklist.de بیشتر نشانی‌هایی را گرد می‌آورد که جای دیگری ورودهای SSH را آزموده‌اند، و این دربارهٔ یک وب‌سرور چیز زیادی نمی‌گوید. به همین دلیل Web RBL فهرست‌های بیگانه را جدا از فهرست مسدودسازی خودش نگه می‌دارد، و به همین دلیل مقدار پیش‌فرض گزارش است. و فهرست مجاز خودمان همیشه برنده است: مشتری‌ای که می‌شناسیم، وزنی بیش از ارزیابی یک شخص ثالث دارد.

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

قوانین کشوری Web RBL: خالی تحویل داده می‌شود، با توضیح

قوانین کشوری خالی تحویل داده می‌شوند و نما دلیلش را می‌گوید.

پیکربندی‌های نادرست را گزارش کنید، نه مسدود

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

  • 1.367 فراخوانی رابط وب یک NAS از نوع QNAP — یک Sync-Client که مقصدش دیگر درست نیست. یک درگاه تنها 962 بار در زد.
  • 65 پرس‌وجوی Autodiscover — یک Outlook که دامنهٔ وب را Exchange خودش می‌پندارد

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

QNAP، Synology، Exchange-Autodiscover، ActiveSync و نیز کلاینت‌های WebDAV، CalDAV و CardDAV شناسایی می‌شوند. الگوها در این میان نام‌های دقیق فایل‌ها و پوشه‌ها را می‌آورند، هرگز پسوندهای صرف را: در همان پوشهٔ /cgi-bin/ فراخوانی‌های بی‌خطر همگام‌سازی درست کنار پروب‌های کلاسیکی مانند printenv.pl قرار دارند.

فهرست مجاز: نشانی‌هایی که هرگز مسدود نمی‌شوند

بهای یک اشتباه برای همهٔ نشانی‌ها یکسان نیست. در مورد یک اسکنر از یک مرکز داده، هشدار کاذب هزینه‌ای ندارد. در مورد طرف مقابل یک تونل شعبه، هزینه‌اش خودِ آن شعبه است.

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

این فهرست هر روز از دو منبع پر می‌شود: از خودِ فایروال با همهٔ طرف‌های مقابل VPN، تا یک تونل تازه‌راه‌اندازی‌شده وابسته به این نباشد که کسی به فهرست مسدودسازی فکر کند — و از بازه‌های نشانیِ منتشرشدهٔ Google و Microsoft برای خزنده‌هایشان. فقط به این ترتیب می‌توان یک Googlebot واقعی را از اسکنری که خودش را چنین می‌نامد تشخیص داد. موتورهای جست‌وجو هرگز نباید مسدود شوند؛ هر که آن‌ها را بیرون بگذارد، وب‌سایتش را بدون راه بازگشت از نمایه‌سازی بیرون می‌برد.

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

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

اطلاعات الزامی و جمع‌آورندگان خودکار داده

صفحهٔ اطلاعات قانونی (Impressum) صفحه‌ای معمولی نیست. باید برای انسان‌ها در دسترس بماند، چون مسدودسازی آن دقیقاً همان تخلفی را می‌آفریند که جمع‌آورنده دنبالش است. در عین حال صفحه‌ای است که نام و نشانی در آن آمده است — و بدین ترتیب هدف برداشت ماشینی.

در موج اخطارهای حقوقی اتریش به دلیل فونت‌های Google ضمیمه‌شده، گزارش‌ها نشان دادند که این نامه‌ها از بازدیدهای منفرد نبودند، بلکه از یک هجوم خودکار فراگیر بودند: میزبان‌های گوناگون و بی‌ارتباط با فاصلهٔ میلی‌ثانیه.

Web RBL این را با تنزل سطح به‌جای استثنا حل می‌کند. مسیر استاندارد /impressum با هیچ الگویی برخورد نمی‌کند و همیشه در دسترس می‌ماند. املاهای بیگانه مانند /impressum.php — که در یک صفحهٔ Odoo نمی‌تواند وجود داشته باشد — گزارش می‌شوند، و هر کس نخواهد برداشت ماشینی را بپذیرد، یک پارامتر را تغییر می‌دهد. sitemap و robots از این امر مستثنا هستند و اساساً قابل مسدودسازی نیستند: آن‌ها هیچ اطلاعات شخصی ندارند و دریافتشان وظیفهٔ هر خزندهٔ موتور جست‌وجو است.

دامنه و شناسه: آنچه در گزارش دسترسی غایب است

گزارش دسترسی werkzeug نه میزبانِ مورد خطاب را ثبت می‌کند و نه شناسهٔ فراخواننده را. Odoo البته هر دو را دریافت می‌کند — بدون میزبان در صورت وجود چند وب‌سایت اصلاً نمی‌توانست وب‌سایت درست را برگزیند. اما بعداً نمی‌توان آن را بازخواند.

Web RBL هر دو را برای هر مورد نگه می‌دارد. این به دو پرسش پاسخ می‌دهد که در غیر این صورت پاسخ‌پذیر نیستند: کدام وب‌سایت مورد خطاب یک پیکربندی نادرست است — و در نتیجه دامنه به کدام مشتری تعلق دارد — و اینکه یک نشانی یک صفحه را می‌بیند یا همهٔ صفحه‌ها را. چند دامنهٔ بی‌ارتباط از همان نشانی نشانهٔ هجوم فراگیر است و امتیاز را بالا می‌برد.

اینکه شناسه چقدر مهم است، در تحلیلی روی یکی از وب‌سایت‌هایمان آشکار شد: بیش از هفتاد درصد کل ترافیک در آنجا به یک فراخوانندهٔ واحد تعلق داشت، پخش‌شده روی بیش از صد نشانی. بدون شناسه شبیه یک اسکرپر توزیع‌شده به نظر می‌رسید. آن GPTBot بود، خزندهٔ OpenAI — که بارها robots.txt را درخواست می‌کرد و کاملاً درست رفتار می‌کرد.

جنبه‌های امنیتی به تفکیک

1. تشخیص پراکسی — خطرناک‌ترین نقطه از همه

اگر Odoo پشت یک Reverse Proxy کار کند و proxy_mode نادرست تنظیم شده باشد، ماژول در هر درخواست همان یک نشانی را می‌بیند: نشانی پراکسی را. آن‌گاه یک مسدودسازی همهٔ بازدیدکنندگان را همزمان بیرون می‌اندازد.

به همین دلیل Web RBL پیش از هر مسدودسازی بررسی می‌کند که تعیین نشانی قابل اعتماد باشد. proxy_mode را همراه با یک سرآیند بازارسال می‌طلبد، اگر بازارسالی بدون proxy_mode برسد کار را رد می‌کند و همین‌طور اگر بیش از یک پراکسی میانی باشد. در صورت تردید، مسدود نمی‌شود.

2. هرگز شبکه‌های خودی

بازه‌های نشانی خصوصی، Loopback، Link-Local و CGNAT به‌طور ثابت مستثنا هستند. به هیچ وجه نمی‌توانند در فهرست قرار بگیرند، حتی با دست. همین در مورد فهرست‌های بیگانه هم صادق است: بازه‌های خصوصی و رزروشده و نیز شبکه‌های به‌طرز مضحکی بزرگ هنگام خواندن دور ریخته می‌شوند.

3. خطای خودی نباید وب‌سایت را با خود ببرد

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

4. نخست مشاهده، بعد مسدودسازی

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

5. الگوهای تنگ به‌جای تورهای پهن

یک بازدیدکنندهٔ اشتباه شناخته‌شده گران‌تر از یک پروب نادیده‌مانده است. به همین دلیل هر الگو سطح خودش را دارد و آن برای هر الگو قابل تغییر است. یک پسوند فایل به‌تنهایی به‌ندرت کافی است: در .php 14.012 پروب واقعی در برابر مشتی پیوند قدیمی ایستاده‌اند، در .asp نسبت معکوس است. چنین تصمیم‌هایی باید اندازه‌گیری شوند، نه تخمین زده شوند.

6. آزادسازی دستی برقرار می‌ماند

هر که نشانی‌ای را آزاد کرده، دلیلی داشته است. یک مورد دیگر این تصمیم را بی‌سروصدا باطل نمی‌کند.

7. فهرست محافظت‌شده است، اما راز نیست

نقطهٔ پایانی توکن می‌طلبد و بدون توکن معتبر با 404 پاسخ می‌دهد، نه با 403 — وجود نشانی به این ترتیب اصلاً تأیید نمی‌شود. مقایسه با زمان ثابت انجام می‌شود. خودِ فهرست چیز محرمانه‌ای ندارد: از نشانی‌هایی تشکیل شده که خودشان در خانهٔ ما را زده‌اند.

8. هیچ راز در دفتر ثبت

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

9. طعمه چیز قابل‌استفاده‌ای فاش نمی‌کند

Web RBL به‌صورت اختیاری به پروب‌ها با محتوای ساختگی پاسخ می‌دهد که یک مقدار قناری یکتا دارد. هر کس این مقدار را بعداً فراخوانی کند، پاسخ جعلی را خوانده و بر پایهٔ آن اقدام کرده است — هشدار کاذب در این میان منتفی است. طعمه‌ها هیچ اطلاعات قابل‌استفاده، هیچ مسیر واقعی و هیچ اطلاعات ورود معتبری ندارند. این قابلیت خاموش تحویل داده می‌شود، زیرا رفتار را به شکل قابل‌مشاهده از بیرون تغییر می‌دهد.

آنچه ماژول نمی‌تواند

جایگزین فایروال و جایگزین Web Application Firewall نیست. الگوهای شناخته‌شدهٔ کاوش در مسیرها، ورودهای ناموفق و رفتار مشکوک را شناسایی می‌کند — نه حمله به فرم‌ها و نه تلاش‌های تزریق در پارامترها را.

علاوه بر این فقط آنچه را می‌بیند که از طریق HTTP برمی‌گردد. آنچه مهاجم با دسترسی‌های به‌یغما‌رفتهٔ پایگاه داده یا صندوق پستی انجام می‌دهد، نادیدنی می‌ماند — و درست به همین دلیل مقادیر قناری مسیر هستند و نه اطلاعات ورود.

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

دسترسی‌پذیری

Web RBL تحت AGPL-3 به‌صورت عمومی در دسترس است و نزد ما به‌صورت عملیاتی روی پنج وب‌سایت اجرا می‌شود:

github.com/Alex0176/odoo-web-rbl

ماژول Odoo 19 Community را پیش‌فرض می‌گیرد و هیچ وابستگی‌ای جز base و web ندارد. اتصال تیکت اختیاری است و به هیچ سامانهٔ تیکت مشخصی نیاز ندارد؛ بدون آن ساده‌اش هیچ اتفاقی نمی‌افتد. کشور مبدأ به پایگاه داده رایگان GeoLite2 از MaxMind نیاز دارد؛ اگر نباشد، فیلد خالی می‌ماند و بقیه‌چیز بدون تغییر کار می‌کند.

مطالعهٔ بیشتر: اینکه Web RBL چگونه در یک معماری امنیتی کامل جا می‌گیرد -- همراه با فایروال، احراز هویت دومرحله‌ای و مجوزها، به‌همراه راهنمای گام‌به‌گام: ترکیب درست معماری امنیتی Odoo 19.

پرسش‌ها، نظرات و گزارش‌های خطا را با کمال میل می‌پذیریم — ترجیحاً به‌صورت Issue در GitHub.