WIUNIX ACADEMY
محافظت از Nginx با Fail2ban؛ لاگ معتبر، مسدودسازی محدود و بازیابی
از ثبت خطای احراز هویت در Nginx تا تشخیص و مسدودسازی موقت IP را مرحلهبهمرحله بررسی کنید؛ ابتدا با اقدام بیخطر و سپس با یک jail محدود روی میزبان آزمایشگاهی.
محیطت را انتخاب کنآموزش متناسب با محیط تو
کجا اجرا میکنی؟
سیستمعامل و نسخه را انتخاب کن تا مراحل، دستورها و راهحلها برای همان محیط نمایش داده شوند.
آموزش متناسب با مقادیر تو
تنظیمات این آموزش
مقادیر نمونه را برای محیط خودت تنظیم کن؛ متن و دستورهای مرتبط با هم تغییر میکنند. رمز، کلید خصوصی و توکن وارد نکن. مقادیر فقط در همین زبانه نگهداری میشوند و به سرور یا لینک اشتراکگذاری فرستاده نمیشوند. پیش از اجرا، DNS، گواهیها و سیاست شبکهٔ واقعی را بررسی کن.
آیپی، دامنه یا پورت مثالها با محیط تو فرق دارد؟ دکمهٔ زیر را باز کن، مقادیر را تغییر بده و «اعمال در آموزش» را بزن؛ سپس دستورهای بهروزشده را کپی کن.
تنظیم مقادیر برای محیط من11 مقدار قابلتغییر
از اینجا شروع کن
در پایان چه چیزی خواهی داشت؟
ساخت jail اختصاصی با ورودی مشخص، آستانهٔ قابل بررسی، محدودهٔ روشن مسدودسازی و مسیر بازگشت.
سیستمعاملها و نسخههای پوششدادهشده
مسیرهای پنج سیستمعامل مستنداتیاند؛ آزمون ایزوله فقط parser و تصمیم action بیخطر را میسنجد. ban واقعی، حفاظت اینترنتی، نصب کامل توزیعها و CDN آزموده نشدهاند. مقادیر سفارشی آزمون اجرا نیستند.
قبل از شروع
- میزبان آزمایشگاهی اختصاصی با Nginx مستقیم، HTTPS معتبر و location دارای Basic Authentication موجود.
- کنسول مستقل، SSH مجاز با کلید و sudo؛ بدون Fail2ban یا مدیر قواعد متعارض قبلی.
- فایل لاگ جدید زیر پوشهٔ استاندارد Nginx و پوشهٔ خصوصی جدید /srv/academy-fail2ban-lab.
- دسترسی به مخزن رسمی همان نسخه و فرایند محافظتشدهٔ مدیریت credential.
این آموزش چه چیزی را پوشش میدهد؟
این مسیر برای مدیر لینوکس است که یک سایت HTTPS روی Nginx میزبان و بخشی با HTTP Basic Authentication فعال دارد. خطاهای 401 همان بخش در لاگی جدا ثبت میشوند. ابتدا تشخیص و اقدام بیخطر را میآزمایید و بعد مسدودسازی موقت را فقط برای پورت TCP سایت فعال میکنید. درخواست بدون نام کاربری هم 401 میگیرد؛ پس شمارش این پاسخها بهتنهایی نشانهٔ قطعی حمله یا رمز اشتباه نیست. تنظیم TLS و امنسازی SSH موضوع این مقاله نیست.
IP لاگ باید با مبدأ بسته یکی باشد
کاربر باید مستقیم به Nginx میزبان روی TCP 443 وصل شود. مقدار $remote_addr از همتای اتصال میآید؛ مسیر تصمیم از لاگ فایل به backend نوع polling، آستانهٔ jail و hook ورودی nftables میرسد. این action فقط TCP را میبندد و HTTP/3 روی UDP را پوشش نمیدهد؛ برای این آزمایش QUIC را فعال نکنید یا مسیر UDP را جدا طراحی و بررسی کنید.
این پیکربندی برای Nginx پشت CDN، پراکسی معکوس، Cloudflare Tunnel، PROXY protocol، real_ip یا پورت منتشرشدهٔ Docker مناسب نیست. پشت پراکسی، مبدأ بسته همان پراکسی است. بستن IP بازیابیشدهٔ کاربر در زنجیرهٔ ورودی سرور معمولاً اثری ندارد؛ بستن IP پراکسی میتواند همه را قطع کند. ترافیک bridge در Docker نیز معمولاً از مسیر forward و NAT عبور میکند.
مقادیر عمومی را از ابتدا هماهنگ کنید
آدرس 203.0.113.20، حساب مجاز admin و پورت فعلی SSH یعنی 22 را با سرور خود تطبیق دهید. دامنهٔ secure.example.net و پورت 443 باید همین حالا برای HTTPS مستقیم کار کنند. 198.51.100.10، IP خروجی واقعی مدیر از نگاه سرور است؛ IP داخلی لپتاپ نیست. اگر مدیریت از IPv6 انجام میشود، IP دقیق را بعداً در ویرایشگر فایل jail اضافه کنید؛ رنج کامل اپراتور یا همهٔ اینترنت را مجاز نکنید. پوشهٔ جدید /srv/academy-fail2ban-lab برای آزمایش و فایل /var/log/nginx/academy-auth.log برای لاگ جداست؛ لاگ را زیر مسیر استاندارد Nginx نگه دارید تا چرخش لاگ بسته آن را پوشش دهد. تنظیمات و پیشرفت سفارشی فقط در sessionStorage همین تب، زبان، مقاله و محیط میمانند؛ پیشرفت پیشفرض در localStorage است. چیزی وارد URL یا سرور نمیشود. رمز و توکن وارد نکنید؛ اعمال مقدار، آزمون نصب نیست.
قدم بعدی
اول مسیر دسترسی و وضعیت میزبان را بررسی کنید
روی میزبان آزمایشگاهی اختصاصی با کنسول مستقل ارائهدهنده کار کنید. نشست فعلی SSH با کلید را باز نگه دارید. پورتها، قواعد فایروال و پیکربندی مؤثر Nginx را محلی ببینید؛ خروجی کامل تنظیمات ممکن است اطلاعات خصوصی داشته باشد و نباید عمومی شود. اگر real_ip فعال است، پراکسی وجود دارد، مسیرها اشغالاند یا Fail2ban و مدیر فایروال قبلی دارید، این مسیر نصب تازه را متوقف کنید و تغییر را با سیاست موجود هماهنگ کنید.
فیلدهای بومی نوع و رابطهها را بررسی میکنند؛ کنترل اضافی این مرحله مسیر غیراستاندارد لاگ و تداخل IP مدیر با دادهٔ آزمایش را رد میکند. symlink والدها و مالک واقعی مسیر را هم پیش از ادامه جدا بررسی کنید.
ترمینال Bash میزبان آزمایشگاهی اختصاصی
set -e
cat /etc/os-release
dpkg-query -W nginx fail2ban nftables 2>/dev/null || true
sudo ss -lntup
if command -v nft >/dev/null; then sudo nft list ruleset; else printf '%s\n' 'nft not installed: inspect current firewall ownership before continuing'; fi
sudo nginx -v
sudo nginx -T
sudo systemctl status fail2ban --no-pager || true
test ! -e "/srv/academy-fail2ban-lab"
test ! -L "/srv/academy-fail2ban-lab"
test ! -e "/var/log/nginx/academy-auth.log"
test ! -L "/var/log/nginx/academy-auth.log"
python3 - <<'PY'
from pathlib import PurePosixPath
from ipaddress import ip_address
log = PurePosixPath('/var/log/nginx/academy-auth.log')
lab = PurePosixPath('/srv/academy-fail2ban-lab')
assert log.parent == PurePosixPath('/var/log/nginx') and log.suffix == '.log'
assert lab.is_absolute() and len(lab.parts) >= 3
assert not any(str(lab).startswith(p) for p in ('/etc/', '/var/log/', '/proc/', '/sys/', '/dev/'))
assert '198.51.100.10' not in ('192.0.2.60', '192.0.2.61')
assert not ip_address('198.51.100.10').is_loopback
print('Public path and fixture-separation checks passed')
PY
پورت مستقیم 443 و مسیرهای آزاد مشخصاند؛ Fail2ban قبلی وجود ندارد و کنسول مستقل در دسترس است.
قدم بعدی
یک نشست دوم مدیریت باز کنید
این دستور روی کامپیوتر مدیر اجرا میشود. کلید میزبان را با مرجع قبلی خود بررسی کنید. اتصال دوم فقط دسترسی موجود را کنترل میکند و تنظیم SSH یا فایروال را تغییر نمیدهد. با وجود محدودبودن action به پورت وب، کنسول مستقل را آماده نگه دارید.
کامپیوتر مدیر؛ هویت SSH موجود
ssh -p 22 admin@203.0.113.20
نشست مجاز دوم باز میشود؛ نشست اول را نبندید.
نسخهٔ upstream با بستهٔ توزیع فرق دارد
در روز بازبینی، نسخهٔ پایدار پروژه 1.1.1 بود. بستهٔ توزیع لزوماً همین شماره را ندارد: فهرست اوبونتو 26.10 نسخهٔ 1.1.0-11، مخزن پایهٔ 24.04 نسخهٔ 1.0.2-3، دبیان 13 نسخهٔ 1.1.0-8 و دبیان 12 نسخهٔ 1.0.2-2 را نشان میداد. مخزن امنیتی و بهروزرسانی ممکن است نسخهٔ دیگری بدهد. صفحهٔ بستهٔ اوبونتو 26.04 پس از تلاش دوباره و مرجع رسمی Launchpad نسخهٔ 1.1.0-9 را نشان دادند؛ candidate را موقع اجرا کنترل و codename نسخهٔ دیگری را جایگزین نکنید. فایل DEB پروژه را روی مالکیت بستهٔ توزیع نصب نکنید. شمارهٔ 1.0.2 بهتنهایی سازگاری با Python 3.12 را ثابت نمیکند؛ patch توزیع مهم است. نسخه و build واقعی Nginx را هم ثبت کنید.