Как да засилите сигурността на вашия производствен 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
в разработката, но не и в производството; иDATABASES
, локална база данни вместо производствена база данни. Тук използвате SQLite база данни за разработка.Забележка: За целите на сигурността изходът DEBUG на Django никога няма да показва никакви настройки, които може да съдържат низовете
API
,KEY
,PASS
,SECRET
,ПОДПИС
илиTOKEN
.Това е, за да се гарантира, че тайните няма да бъдат разкрити, ако случайно внедрите проект в производство с все още активиран
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 за различни уеб функции, като сесийни бисквитки, 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
казва на браузъра, че бисквитките могат да се обработват само през HTTPS. Това означава, че бисквитките, които вашият проект произвежда за дейности, като влизания, ще работят само през криптирана връзка.CSRF_COOKIE_SECURE
е същото катоSESSION_COOKIE_SECURE
, но се отнася за вашия CSRF токен. CSRF токените предпазват от фалшифициране на заявки между сайтове. CSRF защитата на Django прави това, като гарантира, че всички изпратени формуляри (за влизане, регистрации и т.н.) във вашия проект са създадени от вашия проект, а не от трета страна.SECURE_BROWSER_XSS_FILTER
задаваX-XSS-Protection: 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 за Secrets
Последната част на този урок ще ви помогне да използвате
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, като добавите дълъг низ от произволни знаци към него. Така че вместо да отидете на
your_domain/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 за всички комуникации (например поддомейни, бисквитки, CSRF).
- Предотвратяване на XSS (междусайтови скриптове) атаки.
- CSRF (Cross-site request forgery) предотвратяване на атаки.
- Скрит секретен ключ на проекта.
- Скрит URL адрес за влизане на администратор, предотвратяващ груби атаки.
- Отделни настройки за разработка и производство.
Ако се интересувате да научите повече за Django, вижте нашата серия от уроци за разработката на Django.
Освен това, ако все още не сте пуснали проекта си в производство, ето урок на страницата с теми на Django за допълнителни уроци.
И, разбира се, прочетете документацията за настройките на Django за допълнителна информация.