مجله ایرانیکاسرورآموزش سرور، هاست، وردپرس و شبکه
آموزشی

چرا Fail2Ban داخلی‌های واقعی VoIP را مسدود می‌کند؟ رفع Ban اشتباهی بدون کاهش امنیت

اگر Fail2Ban یک داخلی واقعی VoIP را Ban می‌کند، مشکل همیشه «تنظیم اشتباه Fail2Ban» نیست. گاهی همان داخلی واقعاً چند بار Credential اشتباه فرستاده، گاهی چند تلفن پشت یک IP مشترک هستند، گاهی Regex…

چرا Fail2Ban داخلی‌های واقعی VoIP را مسدود می‌کند؟ رفع Ban اشتباهی بدون کاهش امنیت
خلاصه سریع این آموزش

اگر Fail2Ban یک داخلی واقعی VoIP را Ban می‌کند، مشکل همیشه «تنظیم اشتباه Fail2Ban» نیست. گاهی همان داخلی واقعاً چند بار Credential اشتباه فرستاده، گاهی چند تلفن پشت یک IP…

۱۴ دقیقه مطالعه ۰ دیدگاه ۲۷ مهر ۱۴۰۵ آخرین به‌روزرسانی

اگر Fail2Ban یک داخلی واقعی VoIP را Ban می‌کند، مشکل همیشه «تنظیم اشتباه Fail2Ban» نیست. گاهی همان داخلی واقعاً چند بار Credential اشتباه فرستاده، گاهی چند تلفن پشت یک IP مشترک هستند، گاهی Regex بیش از حد گسترده است و گاهی اختلاف ساعت Log باعث می‌شود Fail2Ban چند خط قدیمی را داخل یک بازه کوتاه حساب کند.

در VoIP این موضوع حساس‌تر است، چون یک Public IP می‌تواند نماینده چند تلفن، یک شعبه کامل، یک NAT Gateway یا حتی تعداد زیادی کاربر پشت CGNAT باشد. اگر Fail2Ban همان IP را Ban کند، ممکن است به‌جای یک Client خراب، تمام داخلی‌های آن شبکه قطع شوند.

این راهنما یک روش استاندارد برای تشخیص False Positive در Fail2Ban VoIP ارائه می‌کند: از پیدا کردن Jail و Log واقعی شروع می‌کنیم، Regex را با fail2ban-regex آزمایش می‌کنیم، Timezone را بررسی می‌کنیم، اثر NAT Shared IP و Jailهای recidive را جدا می‌کنیم و در پایان یک Allowlist امن می‌سازیم که امنیت سیستم را بی‌دلیل کاهش ندهد.

اصل مهم: قبل از اینکه IP داخلی واقعی را در ignoreip قرار دهید، اول ثابت کنید چرا Ban شده است. اگر IP متعلق به یک NAT یا CGNAT مشترک باشد، Allowlist کردن آن می‌تواند تمام کاربران پشت همان IP را از کنترل Fail2Ban خارج کند.

فهرست مطالب

False Positive در Fail2Ban یعنی چه؟

Fail2Ban خودش SIP را تحلیل نمی‌کند. این ابزار Log را می‌خواند، خط‌هایی را که با failregex تطبیق دارند پیدا می‌کند و IP مربوط به Failure را شمارش می‌کند. اگر تعداد Matchها در بازه findtime به maxretry برسد، Action مربوط به Jail آن IP را Ban می‌کند.

پس False Positive یعنی Fail2Ban یک IP مشروع را بر اساس Log و Regex به‌عنوان مهاجم تشخیص داده، در حالی که رفتار واقعی آن IP نباید منجر به Ban می‌شده است.

Log event
   |
   v
failregex match?
   |
   +--> no  -> ignore
   |
   +--> yes -> count failure
                 |
                 v
        maxretry inside findtime?
                 |
                 +--> yes -> Ban IP

چرا یک داخلی واقعی VoIP Ban می‌شود؟

علت نشانه
رمز اشتباه یا Credential قدیمی Failure واقعی و تکرارشونده از همان Endpoint
چند دستگاه پشت یک NAT همه با یک Public IP دیده می‌شوند
Regex بیش از حد گسترده Logهای غیرامنیتی هم Match می‌شوند
Timezone اشتباه Failureهای قدیمی داخل بازه جدید شمارش می‌شوند
Jail recidive IP بعد از چند Ban کوتاه، Ban طولانی می‌گیرد
Contact یا App قدیمی یک Softphone خاموش/قدیمی همچنان Credential غلط می‌فرستد
Shared CGNAT IP IP متعلق به یک کاربر واحد نیست
Backend/Logpath اشتباه Jail Log متفاوتی از چیزی که شما بررسی می‌کنید می‌خواند

مرحله ۱: اول مشخص کنید کدام Jail IP را Ban کرده است

وضعیت کل Fail2Ban:

fail2ban-client status

اگر Jail شما asterisk نام دارد:

fail2ban-client status asterisk

فهرست IPهای Banشده همراه زمان:

fail2ban-client get asterisk banip --with-time

برای یک IP خاص:

fail2ban-client get asterisk banned 203.0.113.44

اگر خروجی 1 باشد، آن IP در همان Jail Ban است.

مرحله ۲: تنظیم واقعی Jail را ببینید، نه چیزی که فکر می‌کنید تنظیم شده است

Fail2Ban اجازه می‌دهد تنظیمات از چند فایل .conf و .local ترکیب شوند. بنابراین بهتر است مقدار نهایی را از خود Daemon بخوانید:

fail2ban-client get asterisk findtime
fail2ban-client get asterisk maxretry
fail2ban-client get asterisk bantime
fail2ban-client get asterisk ignoreip
fail2ban-client get asterisk failregex
fail2ban-client get asterisk ignoreregex
fail2ban-client get asterisk logpath

این مرحله مهم است، چون ممکن است شما فایل jail.local را تغییر داده باشید اما Jail دیگری، فایل داخل jail.d یا Backend متفاوتی در حال استفاده باشد.

مستند رسمی Fail2Ban نیز توصیه می‌کند فایل‌های اصلی .conf را مستقیم ویرایش نکنید و Overrideها را در .local یا فایل‌های داخل jail.d قرار دهید تا Updateهای بعدی تنظیمات شما را بازنویسی نکنند.

مرحله ۳: رویداد Ban را در Log خود Fail2Ban پیدا کنید

اگر Log Target پیش‌فرض فایل باشد، معمولاً رویدادهای Ban در /var/log/fail2ban.log دیده می‌شوند:

grep -F "203.0.113.44" /var/log/fail2ban.log

اگر فقط Banها را می‌خواهید:

grep -F "Ban 203.0.113.44" /var/log/fail2ban.log

زمان Ban را یادداشت کنید. بعد دقیقاً همان بازه زمانی را در Log سرویس VoIP بررسی کنید.

مرحله ۴: ببینید Asterisk واقعاً چه چیزی درباره آن IP نوشته است

اگر Asterisk در فایل Log می‌نویسد:

grep -n -F "203.0.113.44" /var/log/asterisk/messages

اگر Log اصلی شما full است:

grep -n -F "203.0.113.44" /var/log/asterisk/full

سؤال اصلی این است: آیا واقعاً چند خط Authentication Failure وجود دارد یا Regex یک پیام بی‌خطر را Failure حساب کرده است؟

اگر Log چیزی شبیه «Failed to authenticate» یا Username/Password Failure واقعی دارد، ممکن است False Positive نباشد؛ یک تلفن، App یا Provision قدیمی هنوز Credential اشتباه دارد.

مرحله ۵: Regex را با fail2ban-regex آزمایش کنید

ابزار رسمی fail2ban-regex برای همین کار ساخته شده است: Log واقعی را در برابر Filter تست می‌کند و نشان می‌دهد چه خط‌هایی Match شده‌اند.

برای Filter رسمی Asterisk:

fail2ban-regex \
  /var/log/asterisk/messages \
  /etc/fail2ban/filter.d/asterisk.conf \
  --print-all-matched

اگر Jail شما Custom Filter دارد، همان فایل را جایگزین کنید.

برای یک نمونه کوچک بهتر است چند خط اطراف Event را جدا کنید و روی همان فایل تست بگیرید تا خروجی خواناتر باشد.

grep -F "203.0.113.44" \
  /var/log/asterisk/messages \
  > /tmp/asterisk-ip-test.log

fail2ban-regex \
  /tmp/asterisk-ip-test.log \
  /etc/fail2ban/filter.d/asterisk.conf \
  --print-all-matched

اگر یک Log سالم یا Warning غیرامنیتی Match می‌شود، مشکل Filter است؛ نه Endpoint.

Regex را در فایل اصلی ویرایش نکنید

Fail2Ban توصیه می‌کند Customizationها در فایل‌های .local انجام شوند. اگر لازم است Filter Asterisk را اصلاح کنید، به‌جای تغییر مستقیم فایل اصلی از فایل Local استفاده کنید:

/etc/fail2ban/filter.d/asterisk.local

قبل از Reload، Configuration را تست کنید:

fail2ban-client -t

سپس:

fail2ban-client reload

نکته: ignoreregex برای بعضی استثناها کاربرد دارد، اما مستند Fail2Ban پیشنهاد می‌کند در صورت امکان Filter اصلی را دقیق‌تر طراحی کنید؛ چون استفاده زیاد از ignoreregex هم خوانایی و هم کارایی را بدتر می‌کند.

مرحله ۶: Timezone اشتباه می‌تواند Failureهای قدیمی را «جدید» نشان دهد

یکی از False Positiveهای سخت، اختلاف ساعت بین Application Log و Fail2Ban است. اگر خط Log Timezone صریح نداشته باشد، Fail2Ban آن را با Timezone سیستم خودش تفسیر می‌کند. مستند رسمی Jail گزینه logtimezone را دقیقاً برای همین وضعیت ارائه می‌کند.

ابتدا ساعت سیستم را ببینید:

date
timedatectl

چند خط از Log را هم ببینید:

tail -n 20 /var/log/asterisk/messages

اگر Log بدون Offset زمانی است و واقعاً مثلاً UTC نوشته می‌شود، می‌توانید در Jail مربوطه مشخص کنید:

[asterisk]
logtimezone = UTC

یا اگر Log واقعاً با Offset ثابت دیگری نوشته می‌شود، همان Offset را بگذارید. Fail2Ban برای logtimezone Offset ثابت مثل UTC+0200 را پشتیبانی می‌کند. این گزینه روی Logهایی که خودشان Timezone صریح دارند اثری ندارد.

Regex و Timezone را با هم تست کنید

fail2ban-regex گزینه Timezone هم دارد:

fail2ban-regex \
  /var/log/asterisk/messages \
  asterisk \
  --timezone=UTC \
  --print-all-matched

به این ترتیب می‌توانید قبل از دست‌زدن به Jail ببینید Parsing زمان چه اثری روی Matchها دارد.

مرحله ۷: اگر Backend شما systemd است، ممکن است اصلاً logpath معیار نباشد

Fail2Ban چند Backend دارد. اگر Jail با backend = systemd اجرا شود، طبق مستند رسمی استفاده از logpath معتبر نیست و Filter باید از journalmatch استفاده کند.

پس اگر شما در /var/log/asterisk/messages چیزی پیدا نمی‌کنید، اول Backend و Journal Match واقعی را بررسی کنید:

fail2ban-client get asterisk journalmatch

و Journal را مستقیم بررسی کنید:

journalctl --since "-15 min" | grep -F "203.0.113.44"

مرحله ۸: NAT Shared IP را تشخیص دهید

این یکی از مهم‌ترین دلایل False Positive در VoIP است. فرض کنید ۲۰ تلفن یک شعبه پشت یک Public IP هستند:

Phone 1001 --\
Phone 1002 ----\
Phone 1003 ------> NAT Gateway ---> 203.0.113.44 ---> PBX
...            /
Phone 1020 ---/

اگر فقط تلفن 1003 Password اشتباه داشته باشد، Fail2Ban ممکن است Public IP 203.0.113.44 را Ban کند؛ در نتیجه تمام ۲۰ تلفن از دید PBX مسدود می‌شوند.

در این وضعیت خود Ban از نظر IP Detection اشتباه نیست؛ مشکل این است که یک IP نماینده چند Endpoint است.

CGNAT از NAT شعبه هم خطرناک‌تر است

در CGNAT ممکن است Public IP مشترک فقط متعلق به شرکت شما نباشد و مشترک‌های دیگری هم پشت همان IP باشند. بنابراین این کار خطرناک است:

ignoreip = 203.0.113.44

اگر این IP یک CGNAT Shared Address باشد، شما عملاً هر Host دیگری که از همان IP عمومی دیده شود را هم از Fail2Ban خارج می‌کنید.

برای Remote Userهای پشت CGNAT، راه‌حل بهتر معمولاً یکی از این‌هاست:

🔹 VPN با IP داخلی قابل‌شناسایی.

🔹 SBC/Registrar عمومی با Policy دقیق‌تر.

🔹 Threshold مناسب‌تر برای Jail VoIP.

🔹 رفع Credential خراب به‌جای Allowlist کردن IP مشترک.

مرحله ۹: Jail recidive ممکن است یک اشتباه کوچک را به Ban طولانی تبدیل کند

Filter رسمی recidive Log خود Fail2Ban را می‌خواند و IPهایی را که چند بار توسط Jailهای دیگر Ban شده‌اند برای مدت طولانی‌تری مسدود می‌کند.

این برای مهاجم‌های تکراری مفید است، اما در VoIP Shared NAT می‌تواند مشکل‌ساز شود:

Shared office IP
   |
   +-- phone A wrong password -> Ban
   |
   +-- phone B stale account -> Ban
   |
   +-- phone C retry storm -> Ban
   |
   v
recidive sees repeated bans
   |
   v
longer ban for entire public IP

برای دیدن وضعیت recidive:

fail2ban-client status recidive
fail2ban-client get recidive banip --with-time

اگر IP مشروع در recidive است، فقط Unban کردن Jail Asterisk کافی نیست؛ باید Ban در recidive را هم بررسی کنید.

recidive را فقط برای Jailهای موردنظر محدود کنید

Filter رسمی recidive اجازه می‌دهد نام Jail هدف را مشخص کنید. مثلاً اگر تصمیم گرفته‌اید recidive فقط روی SSH اعمال شود:

[recidive]
enabled = true
filter = recidive[_jailname="sshd"]

این تصمیم باید با Threat Model شما هماهنگ باشد. هدف خاموش‌کردن recidive نیست؛ هدف این است که یک Shared IP مشروع به‌خاطر رفتار چند Device بی‌دلیل Ban طولانی نگیرد.

مرحله ۱۰: Allowlist را بر اساس «اعتماد واقعی» طراحی کنید

Fail2Ban در ignoreip از IP، CIDR و DNS Host پشتیبانی می‌کند. اما هر IPای نباید صرفاً چون «مشتری ماست» Allowlist شود.

منبع Allowlist؟ دلیل
Loopback بله Localhost
Subnet داخلی VPN مدیریت‌شده معمولاً بله هویت و مسیر کنترل‌شده
IP ثابت دفتر خودتان با بررسی اگر فقط همان سازمان از آن استفاده می‌کند
IP رسمی SIP Provider در Jail مناسب، با بررسی منبع Trusted مشخص
IP خانگی Dynamic معمولاً نه تغییرپذیر
CGNAT Shared IP خیر ممکن است چند مشترک روی آن باشند

نمونه محدود و قابل‌کنترل:

[asterisk]
ignoreip = 127.0.0.1/8 ::1 10.50.0.0/24

در این مثال فقط Loopback و یک Subnet VPN داخلی Allowlist شده‌اند. Range را متناسب با شبکه واقعی خودتان تنظیم کنید.

Allowlist موقت از CLI

برای تست کوتاه:

fail2ban-client set asterisk addignoreip 203.0.113.44

حذف آن:

fail2ban-client set asterisk delignoreip 203.0.113.44

این روش برای تشخیص موقت خوب است، اما Configuration دائمی را در فایل Local مستند کنید.

مرحله ۱۱: IP را فقط بعد از جمع‌آوری Evidence آزاد کنید

برای Unban از Jail مشخص:

fail2ban-client set asterisk unbanip 203.0.113.44

اما قبل از Unban حداقل این موارد را ثبت کنید:

🔹 زمان Ban.

🔹 Jail ایجادکننده Ban.

🔹 Log Lineهای Match‌شده.

🔹 Username/Extension مربوط.

🔹 اینکه IP Shared NAT است یا اختصاصی.

🔹 وجود Ban در recidive.

اگر فوراً Unban کنید و Evidence را از دست بدهید، چند ساعت بعد همان مشکل برمی‌گردد و دوباره از صفر شروع می‌کنید.

Threshold را افزایش دهیم یا نه؟

بالا بردن maxretry اولین راه‌حل نباید باشد. اگر Password یک Endpoint اشتباه است، افزایش Threshold فقط Ban را دیرتر می‌کند.

اما در شبکه‌ای با Shared NAT، Threshold خیلی کم می‌تواند شکننده باشد. مثلاً:

[asterisk]
findtime = 10m
maxretry = 8
bantime = 30m

این فقط نمونه است. عدد مناسب را از Baseline واقعی Registration Failureهای سالم و رفتار Attack تعیین کنید.

یک روش امن برای تنظیم Jail VoIP

[asterisk]
enabled = true
filter = asterisk

logpath = /var/log/asterisk/messages

findtime = 10m
maxretry = 8
bantime = 30m

ignoreip = 127.0.0.1/8 ::1 10.50.0.0/24

اگر Backend شما systemd است، این نمونه را کورکورانه استفاده نکنید؛ همان‌طور که بالاتر گفتیم در Backend سیستم‌دی، journalmatch معیار خواندن Log است.

چطور بفهمیم مشکل از یک App قدیمی است؟

در شرکت‌ها زیاد پیش می‌آید داخلی روی چند Device ثبت شده باشد: تلفن رومیزی، Softphone موبایل، لپ‌تاپ یا App قدیمی. Password روی PBX عوض می‌شود اما یکی از Clientها هنوز Credential قبلی را می‌فرستد.

نشانه:

Same public IP
Same username
Repeated REGISTER
401 / auth failure
Every few seconds

در این حالت Allowlist اشتباه است. باید Client خراب را پیدا کنید، Credential آن را اصلاح کنید یا Registration اضافی را حذف کنید.

چک‌لیست تشخیص False Positive در کمتر از ۱۰ دقیقه

گام بررسی
۱ کدام Jail IP را Ban کرده است؟
۲ زمان دقیق Ban چیست؟
۳ Log واقعی Asterisk در همان زمان چه می‌گوید؟
۴ کدام Regex آن خط را Match کرده است؟
۵ Timezone Log و Fail2Ban یکسان است؟
۶ IP متعلق به یک Endpoint است یا NAT/CGNAT مشترک؟
۷ IP در recidive هم Ban شده است؟
۸ Credential قدیمی یا Client اضافه وجود دارد؟
۹ Allowlist واقعاً امن است؟
۱۰ بعد از اصلاح، Regex و Config دوباره تست شده‌اند؟
Fail2Ban را خاموش نکنید؛ علت False Positive را پیدا کنید

داخلی‌های واقعی VoIP مرتب Ban می‌شوند؟

اگر Log، IP Banشده و Jail را داشته باشید، می‌توان مشخص کرد مشکل از Regex، Timezone، Shared NAT، recidive یا Credential خراب است و بدون حذف لایه امنیتی، تنظیم Fail2Ban را اصلاح کرد.

ایرانیکاسرور می‌تواند برای تهیه VPS، نصب Asterisk/FreePBX، Hardening، Fail2Ban و عیب‌یابی Registrationهای VoIP کمک کند.

تماس با پشتیبانی ایرانیکاسرور: 021-91302467

پرسش‌های رایج

چرا Fail2Ban داخلی واقعی VoIP را Ban می‌کند؟

رایج‌ترین علت‌ها Credential اشتباه، چند Device پشت یک Public IP، Regex بیش از حد گسترده، Timezone اشتباه و Jail recidive هستند.

چطور بفهمیم کدام Regex باعث Ban شده است؟

Log واقعی را با fail2ban-regex و Filter همان Jail تست کنید و از گزینه –print-all-matched برای دیدن خط‌های Match‌شده استفاده کنید.

آیا بهتر است IP مشتری را در ignoreip بگذاریم؟

فقط اگر IP واقعاً Trusted و اختصاصی باشد. IPهای Dynamic یا CGNAT Shared را Allowlist نکنید، چون کاربران دیگری هم ممکن است از همان Public IP دیده شوند.

Timezone چه ارتباطی با False Positive دارد؟

اگر Log بدون Offset زمانی باشد و Fail2Ban آن را با Timezone اشتباه تفسیر کند، Failureهای خارج از بازه ممکن است داخل findtime قرار بگیرند. logtimezone برای همین سناریو وجود دارد.

recidive چه کاری انجام می‌دهد؟

recidive Banهای قبلی Fail2Ban را مانیتور می‌کند و IPهای تکرارشونده را برای مدت طولانی‌تر Ban می‌کند. روی Shared NAT باید اثر آن را با دقت بررسی کنید.

آیا بالا بردن maxretry مشکل را حل می‌کند؟

نه همیشه. اگر Credential یک Client اشتباه باشد فقط Ban را به تأخیر می‌اندازد. ابتدا علت Failure را رفع کنید و بعد Threshold را بر اساس Baseline شبکه تنظیم کنید.

چطور IP را از Ban خارج کنیم؟

با fail2ban-client set JAIL unbanip IP می‌توانید Unban کنید، اما بهتر است قبل از آن Log و Evidence مربوط به Ban را ذخیره کنید.

Fail2Ban را برای VoIP خاموش کنیم؟

خیر. خاموش‌کردن کامل Fail2Ban سطح دفاع در برابر Brute Force را کم می‌کند. بهتر است Regex، Jail، Allowlist و NAT Design را اصلاح کنید.

جمع‌بندی

Ban شدن داخلی واقعی در Fail2Ban معمولاً با یک دستور Unban حل نمی‌شود. ابتدا باید مشخص کنید کدام Jail، کدام Regex و کدام Log Line باعث Ban شده است.

در VoIP، Shared NAT و CGNAT اهمیت ویژه دارند چون یک IP می‌تواند نماینده چند Endpoint باشد. Allowlist کردن چنین IPی امنیت را کاهش می‌دهد و ممکن است تمام کاربران پشت آن IP را از Fail2Ban خارج کند.

Timezone و recidive دو عامل کمتر دیده‌شده اما مهم هستند: Timezone اشتباه می‌تواند Window محاسبه Failureها را خراب کند و recidive می‌تواند Banهای کوتاه تکراری را به Ban طولانی تبدیل کند.

روش درست این است که Evidence را نگه دارید، Regex را با fail2ban-regex تست کنید، Client خراب را پیدا کنید و Allowlist را فقط برای IPها و Subnetهای واقعاً Trusted طراحی کنید.

منابع و مستندات
Regex، ignoreip، logtimezone، Jail Runtime، recidive و روش تست Filter این مقاله با مستندات رسمی Fail2Ban تا ۱۹ اکتبر ۲۰۲۶ بررسی شده‌اند.
Fail2Ban Jail
مرجع ignoreip، ignoreself، ignoreregex، datepattern، logtimezone، backend و ساختار فایل‌های Local.
Fail2Ban Regex
مرجع تست failregex، Filter File، datepattern و Timezone روی Log واقعی.
Fail2Ban Client
مرجع status، banned، banip، ignoreip، failregex، findtime، bantime و Unban Runtime.
Fail2Ban Recidive
مرجع Ban طولانی‌تر برای IPهایی که توسط Jailهای دیگر چند بار Ban شده‌اند و امکان محدودکردن Jail هدف.
Fail2Ban Filters
مرجع failregex و ignoreregex و توصیه به طراحی دقیق Filter به‌جای استثناهای زیاد.

مطلب مرتبط: اگر Fail2Ban روی VPS فعال است، خود SSH و دسترسی مدیریتی را هم امن نگه دارید.

چگونه SSH را امن کنیم؟ از حذف Root Login تا SSH Key و Fail2Ban

اشتراک‌گذاری مقاله
گفت‌وگو درباره آموزش

دیدگاه‌ها (۰)

هنوز دیدگاهی ثبت نشده است.

دیدگاه یا سؤال خود را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *