وبلاگ نت‌آرامآموزش، تجربه و راهکارهای زیرساخت

رفع خطای DisallowedHost و Bad Request 400 در جنگو روی هاست پایتون

آموزش تشخیص و رفع DisallowedHost در Django، تنظیم امن ALLOWED_HOSTS و آزمایش دامنه روی هاست پایتون، همراه با راه‌حل خطاهای مشابه.

انتشار:
توسط تیم فنی نت‌آرام
۷ دقیقه زمان مطالعه
۰ دیدگاه
محتوای تخصصی، ساده و کاربردی
هماهنگ با هویت حرفه‌ای نت‌آرام
بازگشت به لیست مقالات
تصویر شاخص مقاله رفع خطای DisallowedHost و Bad Request 400 در جنگو روی هاست پایتون در وبلاگ نت‌آرام
محتوای آموزشی وبلاگ نت‌آرام
پروژه جنگو روی رایانه شما باز می‌شود، اما بعد از انتقال به هاست و وارد کردن دامنه، صفحه‌ای با پیام «Bad Request (400)» می‌بینید. گاهی در گزارش خطا هم عبارت DisallowedHost یا Invalid HTTP_HOST header ثبت می‌شود. معنی ساده‌اش این است که جنگو نامی را که بازدیدکننده برای رسیدن به سایت استفاده کرده، در فهرست نام‌های مجاز برنامه پیدا نکرده است.
هر خطای ۴۰۰ الزاماً از همین تنظیم نیست. در این آموزش اول نشانه را پیدا می‌کنیم، سپس دامنه درست را به تنظیمات همان برنامه فعال اضافه می‌کنیم و دوباره امتحان می‌کنیم. مثال‌ها برای Django در محیط لینوکس و هاست اشتراکی دارای پنل برنامه پایتون نوشته شده‌اند. نام دکمه‌ها و نسخه‌های قابل انتخاب در پنل‌های مختلف ممکن است فرق کند.

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

وارد cPanel شوید و بخش Setup Python App یا بخشی را باز کنید که برنامه پایتون شما را مدیریت می‌کند. آدرس دامنه، مسیر Application root، نسخه پایتون و فایل شروع برنامه را یادداشت کنید. اگر برنامه را در پنل دیگری ساخته‌اید، اطلاعات مشابه را در همان پنل پیدا کنید. این مسیر با پوشه عمومی سایت یکی نیست و نباید از روی حدس تغییرش داد.
اگر گزینه Terminal یا دسترسی SSH در سرویس شما فعال است، ترمینال را باز کنید. آدرس فرضی زیر فقط نمونه است؛ آن را با مسیر واقعی پروژه جایگزین کنید:
کد / دستورcd ~/myproject pwd ls -la
دستور اول وارد پوشه پروژه می‌شود، دومی مسیر جاری را نشان می‌دهد و سومی فایل‌ها را فهرست می‌کند. دنبال manage.py بگردید. اگر این فایل را نمی‌بینید، شاید یک پوشه بالاتر یا پایین‌تر هستید؛ بی‌هدف فایل‌های برنامه دیگری را تغییر ندهید. قبل از ویرایش فایل تنظیمات، نسخه‌ای از آن را در محلی خارج از پوشه عمومی سایت نگه دارید. اطلاعات محرمانه، به‌خصوص کلید و رمز دیتابیس، نباید در تیکت عمومی یا تصویر ارسالی دیده شوند.

۱. مطمئن شوید خطا واقعاً DisallowedHost است

ابتدا آدرس کامل سایت، با و بدون www، و زمان تقریبی خطا را یادداشت کنید. در پنل برنامه، مسیر گزارش برنامه را پیدا کنید؛ در بعضی حساب‌ها خطا در بخش Metrics → Errors یا در فایل گزارش برنامه دیده می‌شود. نام و محل لاگ به تنظیم میزبان بستگی دارد. به دنبال عبارت‌های DisallowedHost و Invalid HTTP_HOST در همان زمان بگردید. اگر لاگ نامی مانند shop.example.com را نشان داد، همان نام سرنخ اصلی است.
اگر فقط صفحه ۴۰۰ می‌بینید ولی چنین پیامی ثبت نشده، نتیجه قطعی نگیرید؛ مشکل ممکن است از پراکسی، تنظیم دامنه در پنل یا بخش دیگری از برنامه باشد. برای نشان دادن خطای واقعی به کاربران، DEBUG را روی سایت عمومی روشن نکنید؛ این کار ممکن است اطلاعات حساس پروژه را نمایش دهد.
اگر فایل لاگ برنامه در مسیر مشخصی در اختیار دارید، می‌توانید فقط انتهای آن را ببینید. در نمونه زیر، مسیر ساختگی است و باید با مسیر واقعی جایگزین شود:
کد / دستورtail -n 100 ~/myproject/logs/app.log
اگر پیام «No such file» گرفتید، به معنی نبود خطای جنگو نیست؛ مسیر لاگ را از پنل یا ارائه‌دهنده بپرسید. محتوای لاگ را پیش از اشتراک‌گذاری از رمزها و داده‌های کاربران پاک کنید.

۲. تنظیمات واقعاً فعال را بخوانید

ممکن است پروژه چند فایل تنظیمات داشته باشد و شما فایل آزمایشی را تغییر دهید، در حالی که هاست فایل دیگری را اجرا می‌کند. در پنل برنامه، فرمان فعال‌سازی محیط مجازی را کپی و در ترمینال اجرا کنید. نمونه فرمان زیر فقط شکل کلی را نشان می‌دهد؛ مسیر و نسخه خودتان را از پنل بردارید:
کد / دستورsource /home/USER/virtualenv/myproject/3.12/bin/activate python --version python manage.py shell -c 'from django.conf import settings; print("settings:", settings.SETTINGS_MODULE); print("allowed:", settings.ALLOWED_HOSTS); print("debug:", settings.DEBUG)'
خروجی آخر نام ماژول تنظیمات، فهرست میزبان‌های مجاز و وضعیت Debug را نشان می‌دهد. اگر فرمان فعال‌سازی خطا داد، مسیر نمونه را دستکاری نکنید؛ فرمان اختصاصی حساب را از پنل بردارید. اگر manage.py پیدا نشد، دوباره به پوشه درست بروید. اگر فایل تنظیمات شما نیاز به متغیرهای محیطی دارد، همین فرمان را با همان محیطی اجرا کنید که برای برنامه تنظیم شده است؛ تفاوت خروجی ترمینال و برنامه نشانه استفاده از محیط‌های متفاوت است.

۳. دامنه صحیح را به فهرست مجاز اضافه کنید

در فایل تنظیماتی که مرحله قبل نشان داده، مقدار ALLOWED_HOSTS را پیدا کنید. فرض کنیم نشانی واقعی برنامه شما example.com است و می‌خواهید نسخه www هم کار کند:
کد / دستورALLOWED_HOSTS = ["example.com", "www.example.com"]
به جای نام‌های نمونه، دامنه خودتان را بنویسید. فقط نام میزبان لازم است؛ پیشوند https://، مسیرهایی مانند /admin و شماره پورت را داخل این فهرست ننویسید. اگر برنامه روی app.example.com اجرا می‌شود، همان زیردامنه را نیز جداگانه اضافه کنید. وجود دامنه در این فهرست به‌تنهایی DNS را تنظیم نمی‌کند؛ دامنه باید در پنل به برنامه درست وصل شده باشد.
از گذاشتن ستاره به‌عنوان راه‌حل فوری خودداری کنید، مگر اینکه اعتبارسنجی میزبان را جداگانه و درست پیاده‌سازی کرده باشید. ستاره باعث می‌شود جنگو هر نام میزبانی را بپذیرد و مسئولیت کنترل آن به تنظیمات دیگر منتقل شود. به همین شکل، خاموش‌کردن موقت خطای امنیتی با روشن‌کردن Debug راه‌حل نیست.
اگر پروژه مقدار را از متغیر محیطی می‌خواند، باید همان متغیر را در بخش Environment variables پنل برنامه اصلاح کنید؛ تغییر خطی که بعداً با متغیر جایگزین می‌شود اثری ندارد. روش تبدیل متن به فهرست در هر پروژه متفاوت است؛ فاصله و جداکننده را مطابق کد خود برنامه تنظیم کنید، نه بر اساس حدس.

۴. برنامه را راه‌اندازی مجدد و نتیجه را امتحان کنید

تغییر را ذخیره کنید. در پنل برنامه، دکمه Restart مربوط به همان برنامه را بزنید تا تنظیمات جدید بارگذاری شود. سپس صفحه را در پنجره خصوصی مرورگر باز کنید و هر نامی را که به کاربران می‌دهید، جداگانه امتحان کنید. دستور زیر کد پاسخ نشانی نمونه را از ترمینال نشان می‌دهد:
کد / دستورcurl -sS -o /dev/null -w 'HTTP %{http_code}\n' https://example.com/ curl -sS -o /dev/null -w 'HTTP %{http_code}\n' https://www.example.com/
به جای دامنه نمونه، دامنه واقعی را بنویسید. کد 200 یعنی همان درخواست موفق بوده و 301 یا 302 معمولاً یعنی انتقال به نشانی دیگر انجام شده است؛ برای دیدن مقصد، این فرمان را اجرا کنید:
کد / دستورcurl -I https://example.com/
خط Location مقصد انتقال را نشان می‌دهد. اگر نسخه اصلی به www منتقل می‌شود، مقصد هم باید در تنظیمات برنامه و DNS درست باشد. خطای گواهی SSL یا نرسیدن اتصال، مسئله متفاوتی است و پیش از نتیجه‌گیری درباره جنگو باید برطرف شود.

اگر هنوز مشکل وجود دارد

اگر لاگ همچنان DisallowedHost می‌گوید، نام دقیق داخل لاگ را با فهرست فعال مقایسه کنید. تفاوت یک زیردامنه یا بارگذاری‌نشدن تغییرات کافی است. مطمئن شوید تغییر در فایل تنظیمات فعال انجام شده و برنامه درست را Restart کرده‌اید. اگر پشت پراکسی هستید، دستکاری USE_X_FORWARDED_HOST یا اعتمادکردن به هدرهای ارسالی بازدیدکننده می‌تواند خطرناک باشد؛ تنها زمانی آن را تنظیم کنید که پراکسی مورد اعتماد، هدر مربوط را خودش پاک و مقدار معتبر را اضافه کند.
اگر حالا صفحه باز می‌شود ولی فرم با خطای CSRF verification failed روبه‌رو است، آن خطا با ALLOWED_HOSTS یکی نیست. برای Django نسخه‌های جدید، نشانی کامل و مورد اعتماد فرم مانند https://example.com را طبق تنظیمات CSRF_TRUSTED_ORIGINS پروژه بررسی کنید؛ صرف افزودن دامنه به یکی از این دو فهرست دیگری را اصلاح نمی‌کند. ابتدا مطمئن شوید درخواست از همان دامنه و HTTPS مورد انتظار می‌آید.
برای اجرای بررسی‌های پیشنهادی خود جنگو، در محیط درست فرمان زیر را اجرا کنید:
کد / دستورpython manage.py check --deploy
این فرمان ممکن است درباره چند تنظیم دیگر هم هشدار بدهد. هر هشدار را جداگانه بررسی کنید؛ پاک‌شدن هشدارها به‌تنهایی اثبات نمی‌کند تمام مسیرهای سایت درست کار می‌کنند. در پایان صفحه اصلی، ورود و یک فرم معمول را با دامنه واقعی آزمایش کنید و دوباره گزارش خطا را بخوانید.
اگر می‌خواهید برنامه را با پنل و محیط مجازی آماده مدیریت کنید، جزئیات هاست پایتون نت‌آرام را ببینید. پیش از انتخاب سرویس، راهنمای سنجش نیاز به Worker و سرویس‌های پس‌زمینه کمک می‌کند محدودیت‌های برنامه‌تان را بشناسید. توضیح رسمی تنظیمات امنیتی را نیز در چک‌لیست استقرار جنگو بخوانید.
اشتراک‌گذاری:
لینکدینتلگرامایکس
مقاله قبلی
مقاله قبلی وجود ندارد.

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

دیدگاه‌های تاییدشده و پاسخ‌های تیم نت‌آرام