Поиск по сайту:

Как усилить безопасность вашего производственного проекта Django


Автор выбрал программу Write for DOnations.

Введение

Разработка приложения Django может быть удобным занятием, поскольку оно имеет гибкую и масштабируемую структуру. Эта предпосылка распространяется на ориентированные на безопасность настройки Django, которые могут помочь вам подготовить проект к производству. Но есть несколько способов еще больше обезопасить свой проект.

Разделение ваших настроек позволит вам настроить различные конфигурации в зависимости от среды. Использование .env для установки переменных среды или сокрытия конфиденциальных настроек гарантирует, что вы не разглашаете никакие детали, которые могут поставить под угрозу ваш проект. А изменение URL-адресов по умолчанию и других параметров поможет вам избежать распространенных уязвимостей в системе безопасности.

Хотя поначалу реализация этих стратегий может показаться трудоемкой, разработка практического рабочего процесса позволит вам развертывать выпуски вашего проекта без ущерба для безопасности или производительности.

В этом руководстве вы будете использовать рабочий процесс, ориентированный на безопасность, для вашего проекта Django, реализуя и настраивая параметры среды, .env и встроенные параметры безопасности Django. Все эти функции дополняют друг друга и приводят к версии вашего проекта Django, готовой для различных подходов, которые вы можете использовать для развертывания.

Предпосылки

Прежде чем приступить к работе с этим руководством, вам потребуется следующее:

  • Существующий ранее проект Django. Если у вас его еще нет, вы можете использовать наше руководство по установке Django и настройке среды разработки для настройки. В этом руководстве вы будете использовать проект testsite из этого руководства в качестве примера.
    • Для вашего проекта Django вам также потребуется установить Python 3. Вы можете установить его, выполнив шаг 1 нашего руководства «Как установить Python 3 и настроить среду программирования на сервере Ubuntu 20.04».

    • Чтобы использовать сертификат Let’s Encrypt, вам необходимо установить Nginx. Вы можете установить его, следуя нашему руководству Как установить Nginx в Ubuntu 20.04.

    Примечание. Если вы используете существующий проект Django, у вас могут быть другие требования. В этом руководстве предлагается определенная структура проекта; однако при необходимости вы также можете использовать каждый из разделов этого руководства по отдельности.

    Шаг 1 — Реструктуризация настроек Django

    Прежде чем вы приступите к защите своего проекта Django, вам нужно зайти в каталог вашего проекта и активировать виртуальную среду:

    1. cd django-apps
    2. . env/bin/activate

    На этом первом шаге вы начнете с преобразования файла settings.py в конфигурации для конкретной среды. Это хорошая практика, когда вам нужно переместить проект между разными средами, например, между средой разработки и производством. Такое расположение будет означать меньшую перенастройку для разных сред; вместо этого вы будете использовать переменную среды для переключения между конфигурациями, что будет обсуждаться позже в руководстве.

    Создайте новый каталог с именем settings в подкаталоге вашего проекта:

    1. mkdir testsite/testsite/settings

    (Согласно предварительным требованиям, в этом руководстве используется testsite, но вы можете заменить здесь название своего проекта.)

    Этот каталог заменит ваш текущий файл конфигурации settings.py; все ваши настройки на основе среды будут в отдельных файлах, содержащихся в этой папке.

    В новой папке settings создайте три файла Python:

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

    Файл development.py будет содержать настройки, которые вы обычно используете во время разработки. А production.py будет содержать настройки для использования на рабочем сервере. Их следует хранить отдельно, поскольку в рабочей конфигурации будут использоваться параметры, которые не будут работать в среде разработки; например, принудительное использование HTTPS, добавление заголовков и использование производственной базы данных.

    Файл настроек base.py будет содержать настройки, от которых наследуются development.py и production.py. Это делается для уменьшения избыточности и помогает поддерживать чистоту кода. Эти файлы Python заменят settings.py, поэтому теперь вы удалите settings.py, чтобы не путать Django.

    Находясь в каталоге settings, переименуйте settings.py в base.py с помощью следующей команды:

    1. mv ../settings.py base.py

    Вы только что завершили набросок своего нового каталога настроек на основе среды. Ваш проект еще не поймет вашу новую конфигурацию, поэтому дальше вы это исправите.

    Шаг 2 — Использование django-environ

    В настоящее время Django не распознает ваш новый каталог настроек или его внутренние файлы. Итак, прежде чем продолжить работу с настройками среды, необходимо настроить Django на работу с django-environ. Это зависимость, которая загружает переменные среды из файла .env. Это означает, что Django просматривает файл .env в корневом каталоге вашего проекта, чтобы определить, какую конфигурацию настроек он будет использовать.

    Перейдите в корневой каталог вашего проекта, а затем используйте команду ls, чтобы просмотреть содержимое каталога:

    1. cd ../../
    2. ls

    Файлы в корневом каталоге вашего проекта должны выглядеть так:

    Output
    db.sqlite3 manage.py testsite

    Установите django-environ:

    1. pip install django-environ

    Теперь вам нужно настроить Django для использования .env. Для этого вы отредактируете два файла: manage.py для разработки и wsgi.py для производства.

    Начните с открытия manage.py для редактирования с помощью nano или предпочитаемого вами текстового редактора:

    1. nano 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()
    

    Сохраните и закройте manage.py, нажав CTRL+X, нажав Y для сохранения, а затем нажав ENTER.

    Затем откройте wsgi.py для редактирования:

    1. nano 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()
    

    Сохраните и закройте файл, нажав CTRL+X, нажав Y для сохранения, а затем нажав ENTER.

    Код, который вы добавили в оба этих файла, делает две вещи. Во-первых, всякий раз, когда Django запускается — manage.py для запуска разработки, wsgi.py для производства — вы говорите ему искать ваш .env файл. Если файл существует, вы указываете Django использовать файл настроек, рекомендованный .env; в противном случае вы используете конфигурацию разработки по умолчанию.

    Наконец, вы создадите .env в текущем каталоге:

    1. nano .env

    Теперь добавьте следующую строку, чтобы настроить среду разработки:

    DJANGO_SETTINGS_MODULE="testsite.settings.development"
    

    Сохраните и закройте файл, нажав CTRL+X, нажав Y для сохранения, а затем нажав ENTER.

    Примечание. Добавьте .env в свой файл .gitignore, чтобы он никогда не включался в ваши коммиты; вы будете использовать этот файл для хранения таких данных, как пароли и ключи API, которые вы не хотите показывать публично. Каждая среда, в которой работает ваш проект, будет иметь свой собственный .env с настройками для этой конкретной среды.

    Рекомендуется создать .env.example для включения в ваш проект, чтобы вы могли легко создать новый .env везде, где он вам нужен.

    Итак, по умолчанию Django будет использовать testsite.settings.development, но если вы измените DJANGO_SETTINGS_MODULE на testsite.settings.production, например, он начнет использовать вашу производственную конфигурацию. Затем вы заполните конфигурации настроек development.py и production.py.

    Шаг 3 — Создание настроек разработки и производства

    Затем вы откроете файл base.py и добавите конфигурацию, которую хотите изменить для каждой среды, в отдельные файлы development.py и production.py файлы. В файле production.py должны использоваться учетные данные вашей рабочей базы данных, поэтому убедитесь, что они у вас есть.

    Примечание. Вы сами определяете, какие параметры необходимо настроить в зависимости от среды. В этом учебнике будет рассмотрен только общий пример для рабочих параметров и параметров разработки (то есть параметров безопасности и отдельных конфигураций базы данных).

    В этом руководстве вы используете проект Django из обязательного руководства в качестве примера проекта. Вы переместите настройки из base.py в development.py. Начните с открытия development.py:

    1. nano 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'),
        }
    }
    

    Сохраните и закройте файл, нажав CTRL+X, нажав Y для сохранения, а затем нажав ENTER.

    Сначала вы будете импортировать из base.py — этот файл наследует настройки из base.py. Затем вы передадите параметры, которые хотите изменить, для среды разработки. В этом случае настройки, характерные для разработки, следующие: DEBUG, для которого необходимо иметь значение True в разработке, но не в рабочей среде; и БАЗЫ ДАННЫХ, локальная база данных вместо рабочей базы данных. Вы используете базу данных SQLite здесь для разработки.

    Примечание. В целях безопасности выходные данные Django DEBUG никогда не будут отображать какие-либо настройки, которые могут содержать строки API, KEY, PASS, SECRET. , ПОДПИСЬ или ТОКЕН.

    Это делается для того, чтобы секреты не были раскрыты, если вы случайно развернете проект в рабочей среде с включенным DEBUG.

    При этом никогда не развертывайте публично проект с включенным DEBUG. Это только поставит под угрозу безопасность вашего проекта.

    Затем вы добавите в production.py. Откройте файл с помощью следующей команды:

    1. nano testsite/settings/production.py

    Затем добавьте следующий код. Производство будет похоже на development.py, но с другой конфигурацией базы данных и DEBUG со значением False:

    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=''),
        }
    }
    

    Сохраните и закройте файл, нажав CTRL+X, нажав Y для сохранения, а затем нажав ENTER.

    Для приведенного примера конфигурации базы данных вы можете использовать .env для настройки каждого из заданных учетных данных, включая значения по умолчанию. Предполагая, что вы уже настроили базу данных для производственной версии вашего проекта, используйте свою конфигурацию вместо предоставленного примера.

    Теперь вы настроили свой проект для использования различных настроек на основе DJANGO_SETTINGS_MODULE в .env. Учитывая настройки примера, которые вы использовали, когда вы настраиваете свой проект на использование производственных настроек, DEBUG становится False, определяется ALLOWED_HOSTS, и вы начните использовать другую базу данных, которую вы (уже) настроили на своем сервере.

    Шаг 4 — Работа с настройками безопасности Django

    Django включает в себя настройки безопасности, которые вы можете добавить в свой проект. На этом шаге вы добавите в свой проект параметры безопасности, которые считаются необходимыми для любого производственного проекта. Эти настройки предназначены для использования, когда ваш проект общедоступен. Не рекомендуется использовать какие-либо из этих параметров в вашей среде разработки; следовательно, на этом шаге вы ограничиваете эти настройки конфигурацией production.py.

    По большей части эти настройки будут принудительно использовать HTTPS для различных веб-функций, таких как файлы cookie сеанса, файлы cookie CSRF, обновление HTTP до HTTPS и т. д. Поэтому, если вы еще не настроили свой сервер с указывающим на него доменом, пока отложите этот раздел. Если вам нужно настроить сервер, готовый к развертыванию, ознакомьтесь с рекомендациями по этому поводу в Заключении.

    Сначала откройте production.py:

    1. nano 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
    

    • ALLOWED_HOSTS – это список строк, представляющих имена хостов/доменов, которые может обслуживать ваш проект. Это мера безопасности, предотвращающая отравление кэшей и DNS злоумышленником. Дополнительные сведения о ALLOWED_HOSTS см. в документации Django.
    • SECURE_SSL_REDIRECT перенаправляет все HTTP-запросы на HTTPS (кроме исключений). Это означает, что ваш проект всегда будет пытаться использовать зашифрованное соединение. Для этого на вашем сервере должен быть настроен SSL. Обратите внимание: если у вас уже настроен Nginx или Apache, этот параметр будет излишним.
    • SESSION_COOKIE_SECURE сообщает браузеру, что файлы cookie могут обрабатываться только через HTTPS. Это означает, что файлы cookie, создаваемые вашим проектом для таких действий, как вход в систему, будут работать только через зашифрованное соединение.
    • CSRF_COOKIE_SECURE — это то же самое, что и SESSION_COOKIE_SECURE, но применяется к вашему токену CSRF. Токены CSRF защищают от подделки межсайтовых запросов. Защита Django CSRF делает это, гарантируя, что любые формы, отправленные (для входа, регистрации и т. д.) в ваш проект, были созданы вашим проектом, а не третьей стороной.
    • SECURE_BROWSER_XSS_FILTER устанавливает X-XSS-защиту: 1; заголовок mode=block для всех ответов, в которых его еще нет. Это гарантирует, что третьи стороны не смогут внедрить скрипты в ваш проект. Например, если пользователь сохраняет сценарий в вашей базе данных с помощью общедоступного поля, когда этот сценарий извлекается и отображается для других пользователей, он не будет выполняться.

    Сохраните и закройте файл, нажав CTRL+X, нажав Y для сохранения, а затем нажав ENTER.

    Если вы хотите узнать больше о различных настройках безопасности, доступных в Django, ознакомьтесь с их документацией.

    Предупреждение: в документации Django указано, что вы не должны полностью полагаться на SECURE_BROWSER_XSS_FILTER. Никогда не забывайте проверять и дезинфицировать ввод.

    Дополнительные настройки

    Следующие настройки предназначены для поддержки HTTP Strict Transport Security (HSTS) — это означает, что весь ваш сайт должен постоянно использовать SSL.

    • SECURE_HSTS_SECONDS – это время в секундах, на которое устанавливается HSTS. Если вы установите это значение на час (в секундах), каждый раз, когда вы посещаете веб-страницу на своем веб-сайте, он сообщает вашему браузеру, что в течение следующего часа HTTPS — единственный способ посетить этот сайт. Если в течение этого часа вы посетите небезопасную часть своего веб-сайта, браузер выдаст ошибку, и небезопасная страница будет недоступна.
    • SECURE_HSTS_PRELOAD работает, только если установлено значение SECURE_HSTS_SECONDS. Этот заголовок указывает браузеру на предварительную загрузку списка HSTS.
    • SECURE_HSTS_INCLUDE_SUBDOMAINS применяет заголовок HSTS ко всем субдоменам. Включение этого заголовка означает, что и your_domain, и unsecure.your_domain потребуют шифрования, даже если unsecure.your_domain не связан с этим проектом Django.< /li>

    Предупреждение. Неправильная настройка этих дополнительных параметров может привести к поломке вашего сайта на значительное время.

    Перед реализацией этих настроек прочитайте документацию Django по HSTS.

    Необходимо учитывать, как эти настройки будут работать с вашим собственным проектом Django; в целом, обсуждаемая здесь конфигурация является хорошей основой для большинства проектов Django. Далее вы рассмотрите дальнейшее использование .env.

    Шаг 5 — Использование django-environ для секретов

    Заключительная часть этого руководства поможет вам использовать django-environ. Это позволит вам скрыть определенную информацию, например SECRET_KEY вашего проекта или URL-адрес входа администратора. Это отличная идея, если вы собираетесь публиковать свой код на таких платформах, как GitHub или GitLab, поскольку эти секреты не будут опубликованы. Вместо этого всякий раз, когда вы первоначально настраиваете свой проект в локальной среде или на сервере, вы можете создать новый файл .env и определить эти секретные переменные.

    Вы должны скрыть свой SECRET_KEY, чтобы начать работу над этим в этом разделе.

    Откройте файл .env в корневом каталоге вашего проекта:

    1. nano .env

    И добавьте следующую строку, заменив your_secret_key вашими секретными строками:

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

    Затем сохраните и закройте файл, нажав CTRL+X, нажав Y для сохранения, а затем нажав ENTER.

    Затем откройте base.py:

    1. nano testsite/settings/base.py

    Обновите переменную SECRET_KEY следующим образом:

    . . .
    <^>import environ
    
    env = environ.Env()
    environ.Env.read_env()<^>
    
    SECRET_KEY = env('SECRET_KEY')
    . . .
    

    Примечание. SECRET_KEY не следует заменять фактическим секретным ключом. Переменную SECRET_KEY следует оставить как есть, а фактический секретный ключ следует добавить в файл .env.

    Затем сохраните и закройте файл, нажав CTRL+X, нажав Y для сохранения, а затем нажав ENTER. Теперь ваш проект будет использовать SECRET_KEY, расположенный в .env.

    Наконец, вы скроете свой URL-адрес администратора, добавив к нему длинную строку случайных символов. Поэтому вместо ваш_домен/admin вы перейдете на your_domain/very_secret_url/admin. Это гарантирует, что ботам и незнакомцам будет трудно найти ваш URL-адрес администратора, и, следовательно, им будет труднее пытаться взломать ваш логин администратора.

    Откройте .env еще раз:

    1. nano .env

    И добавьте переменную SECRET_ADMIN_URL:

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

    Сохраните и закройте файл, нажав CTRL+X, нажав Y для сохранения, а затем нажав ENTER.

    Теперь вы скажете Django скрыть URL-адрес администратора с помощью SECRET_ADMIN_URL:

    1. nano testsite/urls.py

    Примечание. Не забудьте заменить very_secret_url своим собственным секретным URL.

    Если вы хотите использовать случайные строки для этой переменной, Python предоставляет фантастические примеры, которые они дают, это отличные способы создания небольших программ Python для создания безопасных случайных строк.

    Отредактируйте URL-адрес администратора следующим образом:

    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),
    ]
    

    Сохраните и закройте файл, нажав CTRL+X, нажав Y для сохранения, а затем нажав ENTER.

    Теперь вы можете найти страницу входа администратора по адресу /very_secret_url/admin/, а не просто /admin/:

    Заключение

    В этом руководстве вы настроили текущий проект Django для удобного использования в различных средах. Теперь ваш проект использует django-environ для обработки секретов и настроек. Теперь в ваших производственных настройках включены встроенные функции безопасности Django.

    Если вы включили все рекомендуемые компоненты безопасности и повторно реализовали настройки в соответствии с указаниями, ваш проект будет иметь следующие ключевые функции:

    • SSL/HTTPS для всех коммуникаций (например, субдомены, файлы cookie, CSRF).
    • Предотвращение атак XSS (межсайтовый скриптинг).
    • Предотвращение атак CSRF (подделка межсайтовых запросов).
    • Скрытый секретный ключ проекта.
    • Скрытый URL-адрес для входа администратора, предотвращающий атаки методом грубой силы.
    • Отдельные настройки для разработки и производства.

    Если вы хотите узнать больше о Django, ознакомьтесь с нашей серией руководств по разработке Django.

    Кроме того, если вы еще не запустили свой проект в производство, вот учебник на странице темы Django для дальнейших руководств.

    И, конечно же, ознакомьтесь с документацией по настройкам Django для получения дополнительной информации.