Как усилить безопасность вашего производственного проекта 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, вам нужно зайти в каталог вашего проекта и активировать виртуальную среду:
- cd django-apps
- . env/bin/activate
На этом первом шаге вы начнете с преобразования файла
settings.py
в конфигурации для конкретной среды. Это хорошая практика, когда вам нужно переместить проект между разными средами, например, между средой разработки и производством. Такое расположение будет означать меньшую перенастройку для разных сред; вместо этого вы будете использовать переменную среды для переключения между конфигурациями, что будет обсуждаться позже в руководстве.Создайте новый каталог с именем
settings
в подкаталоге вашего проекта:- mkdir testsite/testsite/settings
(Согласно предварительным требованиям, в этом руководстве используется
testsite
, но вы можете заменить здесь название своего проекта.)Этот каталог заменит ваш текущий файл конфигурации
settings.py
; все ваши настройки на основе среды будут в отдельных файлах, содержащихся в этой папке.В новой папке
settings
создайте три файла Python:- cd testsite/testsite/settings
- 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
с помощью следующей команды:- mv ../settings.py base.py
Вы только что завершили набросок своего нового каталога настроек на основе среды. Ваш проект еще не поймет вашу новую конфигурацию, поэтому дальше вы это исправите.
Шаг 2 — Использование django-environ
В настоящее время Django не распознает ваш новый каталог настроек или его внутренние файлы. Итак, прежде чем продолжить работу с настройками среды, необходимо настроить Django на работу с
django-environ
. Это зависимость, которая загружает переменные среды из файла.env
. Это означает, что Django просматривает файл.env
в корневом каталоге вашего проекта, чтобы определить, какую конфигурацию настроек он будет использовать.Перейдите в корневой каталог вашего проекта, а затем используйте команду
ls
, чтобы просмотреть содержимое каталога:- cd ../../
- ls
Файлы в корневом каталоге вашего проекта должны выглядеть так:
Outputdb.sqlite3 manage.py testsiteУстановите
django-environ
:- pip install django-environ
Теперь вам нужно настроить Django для использования
.env
. Для этого вы отредактируете два файла:manage.py
для разработки иwsgi.py
для производства.Начните с открытия
manage.py
для редактирования с помощьюnano
или предпочитаемого вами текстового редактора:- 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
для редактирования:- 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
в текущем каталоге:- 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
:- 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
. Откройте файл с помощью следующей команды:- 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
:- 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
в корневом каталоге вашего проекта:- nano .env
И добавьте следующую строку, заменив
your_secret_key
вашими секретными строками:DJANGO_SETTINGS_MODULE="testsite.settings.development" SECRET_KEY="your_secret_key"
Затем сохраните и закройте файл, нажав
CTRL+X
, нажавY
для сохранения, а затем нажавENTER
.Затем откройте
base.py
:- 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
еще раз:- 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
:- 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 для получения дополнительной информации.