تغییرات اخیر

در اینجا اطلاعیه‌ها، نسخه‌ها و تغییرات جدید لیارا فهرست می‌شوند.

چگونه امنیت پروژه Django در محیط تولید را افزایش دهیم؟


۱۵ آبان ۱۴۰۴

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

یکی از بهترین روش‌ها، تقسیم تنظیمات پروژه است تا بتوانید پیکربندی‌های متفاوتی برای محیط‌های مختلف ایجاد کنید. استفاده از فایل .env برای ذخیره متغیرهای محیطی یا پنهان کردن اطلاعات حساس، به شما این اطمینان را می‌دهد که هیچ جزئیات محرمانه‌ای افشا نشود و پروژه‌تان در امان بماند. همچنین، تغییر URLهای پیش‌فرض و سایر تنظیمات، از آسیب‌پذیری‌های رایج جلوگیری می‌کند.

هرچند در ابتدا پیاده‌سازی این استراتژی‌ها ممکن است زمان‌بر به نظر برسد، اما با ایجاد یک جریان عملی، می‌توانید نسخه‌های جدید پروژه را بدون کاهش امنیت یا بهره‌وری مستقر کنید.

در این راهنما از لیارا، یک جریان کاری امنیتی برای پروژه Django خود پیاده‌سازی خواهید کرد.

هاست Django، بدون نیاز به پیکربندی و انجام تنظیمات، به‌راحتی وب‌سایت خود را راه‌اندازی کنید.
✅ دامنه‌ رایگان ✅ ترافیک نامحدود ✅ هزینه ساعتی
خرید هاست ابری Django

آنچه در ادامه خواهید خواند:

  • پیش‌نیازها
  • گام اول: بازسازی تنظیمات Django
  • گام دوم: استفاده از django-environ
  • گام سوم: ایجاد تنظیمات توسعه و تولید
  • گام چهارم: کار با تنظیمات امنیتی Django
  • گام پنجم: استفاده از django-environ برای اسرار
  • جمع بندی

پیش‌نیازها

پیش از شروع بررسی کنید تا موارد زیر را در اختیار داشته باشید.

گام اول: بازسازی تنظیمات Django

قبل از ورود به جزئیات امنیتی، به دایرکتوری پروژه بروید و محیط مجازی را فعال کنید:

cd django-apps
. env/bin/activate

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

یک دایرکتوری جدید به نام settings در زیردایرکتوری پروژه ایجاد کنید:

mkdir testsite/testsite/settings

(طبق پیش‌نیازها، از testsite استفاده خواهیم کرد، اما نام پروژه خودتان را جایگزین کنید.)

این دایرکتوری جایگزین فایل settings.py فعلی می‌شود؛ تمام تنظیمات محیطی در فایل‌های جداگانه در این پوشه قرار می‌گیرند.

در پوشه settings جدید، سه فایل پایتون بسازید:

cd testsite/testsite/settings
touch base.py development.py production.py

فایل development.py: شامل تنظیماتی است که معمولا در توسعه از آن استفاده می‌کنید و برای سرور تولید می‌باشد. این دو را جدا نگه دارید به این دلیل ‌که تولید به تنظیماتی نیاز دارد که در توسعه کار نمی‌کنند. مانند:

  • اضافه کردن هدرها
  • استفاده از پایگاه داده تولید

فایل base.py تنظیمات مشترکی دارد که development.py و production.py از آن ارث‌بری می‌کنند. این کار تکرار کد را کم می‌کند و کد را تمیز نگه می‌دارد. این فایل‌ها جایگزین settings.py می‌شوند، پس settings.py را حذف کنید تا Django گیج نشود.

در دایرکتوری settings، نام فایل settings.py را به base.py تغییر دهید:

mv ../settings.py base.py

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

گام دوم: استفاده از django-environ

در حال حاضر، Django پوشه تنظیمات جدید و فایل‌های داخل آن را نمی‌شناسد. پس قبل از ادامه، باید Django را با django-environ سازگار کنید. این وابستگی متغیرهای محیطی را از فایل .env بارگذاری می‌کند. یعنی به فایل .env در ریشه پروژه نگاه می‌کند تا تصمیم بگیرد کدام پیکربندی تنظیمات را استفاده کند.

به ریشه پروژه بروید و محتوای دایرکتوری را با ls ببینید:

cd ../../
ls

فایل‌ها باید چیزی شبیه خروجی زیر باشند:

Output
db.sqlite3  manage.py  testsite

django-environ را نصب کنید:

pip install django-environ

حال Django را برای استفاده از .env پیکربندی کنید. دو فایل را ویرایش خواهیم کرد:

  • manage.py برای توسعه
  • wsgi.py برای تولید

ابتدا manage.py را باز کنید:

nano manage.py

کد زیر را اضافه کنید:

testsite/manage.py
import os
import sys
import environ

environ.Env.read_env()

def main():
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'testsite.settings')

    try:
        from django.core.management import execute_from_command_line
    except ImportError as exc:
        raise ImportError(
            "Couldn't import Django. Are you sure it's installed and "
            "available on your PYTHONPATH environment variable? Did you "
            "forget to activate a virtual environment?"
        ) from exc
    execute_from_command_line(sys.argv)


if __name__ == '__main__':
    main()

فایل را ذخیره و ببندید برای این کار: (CTRL+X، Y، ENTER).

حال wsgi.py را باز کنید:

nano testsite/wsgi.py

خطوط برجسته‌شده را اضافه کنید:

testsite/testsite/wsgi.py

import os
import environ

environ.Env.read_env()

from django.core.wsgi import get_wsgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'testsite.settings')

application = get_wsgi_application()

فایل را ذخیره و ببندید.

این کد دو عملیات را انجام می‌دهد: هر بار که Django اجرا می‌شود (manage.py برای توسعه، wsgi.py برای تولید)، به دنبال .env می‌گردد. اگر فایل وجود داشته باشد، از پیکربندی پیشنهادی آن استفاده می‌کند؛ در غیر این صورت، به توسعه پیش‌فرض برمی‌گردد.

فایل .env را در دایرکتوری فعلی بسازید:

nano .env

خط زیر را اضافه کنید تا محیط را به توسعه تنظیم کند:

testsite/.env
DJANGO_SETTINGS_MODULE="testsite.settings.development"

فایل را ذخیره و ببندید.

  • نکته مهم و حائز اهمیت:
    .env را به .gitignore اضافه کنید تا در کامیت‌ها وارد نشود. این فایل برای داده‌های حساس مانند رمزها و کلیدهای API است. هر محیطی .env خودش را خواهد داشت.
  • در حالت پیش‌فرض، Django از testsite.settings.development استفاده می‌کند، اما اگر DJANGO_SETTINGS_MODULE را به testsite.settings.production تغییر دهید، به پیکربندی تولید سوئیچ می‌شود.

گام سوم: ایجاد تنظیمات توسعه و تولید

base.py را باز کنید و تنظیماتی که می‌خواهید برای هر محیط تغییر دهید، به فایل‌های جداگانه منتقل کنید. production.py به اعتبارهای پایگاه داده تولید نیاز دارد، پس آن‌ها را آماده کنید.

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

تنظیمات را از base.py به development.py منتقل کنید. development.py را باز کنید:

nano testsite/settings/development.py

کد زیر را اضافه کنید:

testsite/testsite/settings/development.py
import os
from .base import *

DEBUG = True

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

فایل را ذخیره و ببندید.

توجه: برای امنیت، خروجی DEBUG Django هرگز تنظیماتی با رشته‌هایی مانند:

  • API
  • KEY
  • PASS
  • SECRET
  • SIGNATURE
  • TOKEN

را نشان نمی‌دهد.

production.pyرا اضافه کنید:

nano testsite/settings/production.py

کد زیر را اضافه کنید. شبیه development.py است اما با پیکربندی پایگاه داده متفاوت و DEBUG بر روی False:

testsite/testsite/settings/production.py
import os
from .base import *
import environ

env = environ.Env()
environ.Env.read_env()

DEBUG = False

ALLOWED_HOSTS = []

DATABASES = {
    'default': {
        'ENGINE': env('SQL_ENGINE', default='django.db.backends.sqlite3'),
        'NAME': env('SQL_DATABASE', default=os.path.join(BASE_DIR, 'db.sqlite3')),
        'USER': env('SQL_USER', default='user'),
        'PASSWORD': env('SQL_PASSWORD', default='password'),
        'HOST': env('SQL_HOST', default='localhost'),
        'PORT': env('SQL_PORT', default=''),
    }
}

فایل را ذخیره و ببندید.

گام چهارم: کار با تنظیمات امنیتی Django

Django تنظیمات امنیتی آماده‌ای دارد که می‌توانید آن‌ها را اضافه کنید. در این گام، تنظیمات ضروری را برای تولید اضافه می‌کنید. البته توجه داشته باشید که برای زمانی که پروژه عمومی است از آن استفاده می‌شود و برای توسعه توصیه می‌شود. بنابراین آن‌ها را فقط به production.py محدود کنید.

ابتدا production.py را باز کنید:

nano testsite/settings/production.py

تنظیمات برجسته‌شده را اضافه کنید که برای پروژه‌تان مناسب باشد، از کد زیر استفاده کنید:

testsite/testsite/settings/production.py
import os
from .base import *
import environ

env = environ.Env()
environ.Env.read_env()

DEBUG = False

ALLOWED_HOSTS = ['your_domain', 'www.your_domain']

DATABASES = {
    'default': {
        'ENGINE': env('SQL_ENGINE', default='django.db.backends.sqlite3'),
        'NAME': env('SQL_DATABASE', default=os.path.join(BASE_DIR, 'db.sqlite3')),
        'USER': env('SQL_USER', default='user'),
        'PASSWORD': env('SQL_PASSWORD', default='password'),
        'HOST': env('SQL_HOST', default='localhost'),
        'PORT': env('SQL_PORT', default=''),
    }
}

SECURE_SSL_REDIRECT = True

SESSION_COOKIE_SECURE = True

CSRF_COOKIE_SECURE = True

SECURE_BROWSER_XSS_FILTER = True

فایل را ذخیره و ببندید.

برای اطلاعات بیشتر در مورد تنظیمات امنیتی Django، مستندات‌ را مشاهده و بررسی کنید.

نکته بسیار مهم: مستندات Django می‌گوید کاملا به SECURE_BROWSER_XSS_FILTER تکیه نکنید. همیشه ورودی‌ها را اعتبارسنجی و پاک‌سازی کنید.

تنظیمات اضافی

تنظیمات زیر برای پشتیبانی از HTTP Strict Transport Security (HSTS) هستند. به این معنی است که سایت همیشه باید از SSL استفاده کند.

  • SECURE_HSTS_SECONDS زمان HSTS در ثانیه است. اگر یک ساعت تنظیم کنید، هر بازدیدی به مرورگر می‌گوید برای آن ساعت فقط HTTPS مجاز است. اگر بخشی ناامن بازدید شود، خطا نشان می‌دهد.
  • SECURE_HSTS_PRELOAD اگر SECURE_HSTS_SECONDS تنظیم شده باشد کار می‌کند. این سایت را برای پیش‌بارگذاری در لیست سخت‌کد شده مرورگرها مثل فایرفاکس و کروم اضافه می‌کند. سایت همیشه باید رمزنگاری‌شده باشد. مراقب باشید؛ اگر بعداً رمزنگاری را بردارید، حذف از لیست هفته‌ها طول می‌کشد.
  • SECURE_HSTS_INCLUDE_SUBDOMAINS HSTS را به همه زیردامنه‌ها اعمال می‌کند. یعنی both your_domain و unsecure.your_domain نیاز به رمزنگاری دارند، حتی اگر unsecure.your_domain به این پروژه مربوط نباشد.

هشدار: پیکربندی نادرست این تنظیمات می‌تواند سایت را برای مدت طولانی خراب کند.

قبل از پیاده‌سازی، مستندات HSTS Django را بخوانید.

این تنظیمات را بر اساس پروژه خود ارزیابی کنید؛ این پیکربندی پایه خوبی برای بیشتر پروژه‌های Django است. حالا به استفاده بیشتر از .env می‌پردازیم.

گام پنجم: استفاده از django-environ برای اسرار

بخش نهایی، بهره‌برداری بیشتر از django-environ است. این به پنهان کردن اطلاعاتی مثل SECRET_KEY پروژه یا URL ادمین کمک می‌کند. عالی برای انتشار کد روی GitHub یا GitLab، چون اسرار منتشر نمی‌شوند. در عوض، هر بار پروژه را روی محیط محلی یا سرور تنظیم می‌کنید، .env جدید بسازید و متغیرهای secret را تعریف کنید.

SECRET_KEY را باید پنهان کنید، پس از آن شروع می‌کنیم.

.env در ریشه پروژه را باز کنید:

nano .env

خط زیر را اضافه کنید و your_secret_key را با رشته امن خود جایگزین کنید:

testsite/.env
DJANGO_SETTINGS_MODULE="testsite.settings.development"
SECRET_KEY="your_secret_key"

فایل را ذخیره و ببندید.

حالا base.py را باز کنید:

nano testsite/settings/base.py

متغیر SECRET_KEY را بروزرسانی کنید:

testsite/testsite/settings/base.py
. . .
import environ

env = environ.Env()
environ.Env.read_env()

SECRET_KEY = env('SECRET_KEY')
. . .

توجه: SECRET_KEY را با کلید واقعی جایگزین نکنید. متغیر همان بماند و کلید واقعی در .env برود.

فایل را ذخیره و ببندید. پروژه حالا SECRET_KEY از .env استفاده می‌کند.

در نهایت، URL ادمین را با اضافه کردن رشته‌ای طولانی از کاراکترهای تصادفی پنهان کنید. به جای your_domain/admin، به your_domain/very_secret_url/admin بروید. این کار پیدا کردن URL ادمین را برای بات‌ها و افراد غریبه سخت می‌کند و brute force را دشوارتر.

.env را دوباره باز کنید:

nano .env

متغیر SECRET_ADMIN_URL را اضافه کنید:

testsite/.env
DJANGO_SETTINGS_MODULE="testsite.settings.development"
SECRET_KEY="your_secret_key"
SECRET_ADMIN_URL="very_secret_url"

فایل را ذخیره و ببندید.

حالا Django را برای پنهان کردن URL ادمین با SECRET_ADMIN_URL تنظیم کنید:

nano testsite/urls.py

توجه: very_secret_url را با URL امن خود جایگزین کنید.

اگر رشته‌های تصادفی می‌خواهید، کتابخانه secrets.py پایتون عالی است برای تولید آن‌ها. مثال‌های‌شان برای برنامه‌های کوچک امن عالی هستند.

URL ادمین را ویرایش کنید:

testsite/testsite/urls.py
from django.contrib import admin
from django.urls import path
import environ

env = environ.Env()
environ.Env.read_env()

urlpatterns = [
    path(env('SECRET_ADMIN_URL') + '/admin/', admin.site.urls),
]

فایل را ذخیره و ببندید.

حالا صفحه لاگین ادمین در /very_secret_url/admin/ است نه /admin/:

جمع بندی

در این راهنما، پروژه Django خود را برای استفاده آسان و امن در محیط‌های مختلف پیکربندی کردید. با تقسیم تنظیمات به فایل‌های مجزا برای توسعه و تولید، استفاده از .env برای مخفی کردن اطلاعات حساس مثل SECRET_KEY و URL ادمین، و فعال‌سازی ویژگی‌های امنیتی داخلی Django مانند HTTPS، حفاظت در برابر XSS و CSRF، پروژه‌ای امن و آماده برای استقرار ساختید. این رویکرد نه تنها امنیت پروژه را تقویت می‌کند، بلکه امکان جابه‌جایی سریع بین محیط‌ها را بدون کاهش بهره‌وری فراهم می‌آورد. برای اطلاعات بیشتر، مستندات Django و راهنماهای مرتبط را بررسی کنید.

به اشتراک بگذارید

برچسب‌ها: