З великою силою приходить і велика відповідальність. Так само і з вашим кабінетом адміністратора в Django: чим він потужніший, тим краще потрібно захищати його від сторонніх.
В цій статті я розкажу про п'ять способів вберегти адміністративний кабінет Django від стороннього втручання.
#1 Змініть URL адмінки
Кожен фреймворк має свої особливості, за якими його можна ідентифікувати, і Django не виключення. Досвідчений розробник, нападник чи просто технічно-підкований користувач може відрізнити сайт на Django за кукісами чи URL'ами.
Після того, як нападник дізнається, що сайт написаний на Django, він, скоріше всього, перейде (і намагатиметься зламати) на сторінку /admin.
І щоб для нього все було не так просто, я рекомендую змінити стандартний URL на інший, який не так просто вгадати.
В url.py
вашого проекту змініть базовий URL для кабінету адміністратора:
urlpatterns += i18n_patterns(
url(r'^super-secret/', admin.site.urls, name='admin'),
)
Змініть «super-secret» на назву, яку ви і ваша команда спроможні запам'ятати, і все! Ну, тобто, це не вбереже ваш сайт від всіх нападників, але це вже гарний старт!
#2 Візуально відділіть середовища
Користувачі та адміністратори теж люди, а люди можуть помилятися. Коли в вас є декілька середовищ (для розробки, QA, тестування та продакшн), операція, виконана не в тому середовищі, може коштувати дуже дорого. Не вірите? Спитайте в gitlab.
Щоб зменшити шанси на таку помилку, ми візуально відділяємо наші середовища.
Перш за все, вам потрібно якось ці середовища відрізняти. В нас є змінна ENVIRONMENT_NAME
, в якій знаходиться назва оточення і змінна ENVIRONMENT_COLOR
, в якій зберігається колір для індикатора.
Щоб додати індикатор на кожну сторінку, ми перевизначаємо базовий шаблон:
# app/templates/admin/base_site.html
{% extends "admin/base_site.html" %}
{% block extrastyle %}
<style type=""text/css"">
body:before {
display: block;
line-height: 35px;
text-align: center;
font-weight: bold;
text-transform: uppercase;
color: white;
content: "{{ ENVIRONMENT_NAME }}";
background-color: {{ ENVIRONMENT_COLOR }};
}
</style>
{% endblock %}
А щоб зробити наші змінні з settings.py
доступними в шаблонах, ми використовуємо обробник контексту:
# app/context_processors.py
from django.conf import settings
def from_settings(request):
return {
'ENVIRONMENT_NAME': settings.ENVIRONMENT_NAME,
'ENVIRONMENT_COLOR': settings.ENVIRONMENT_COLOR,
}
Щоб зареєструвати його, потрібно додати наступний код в settings.py
:
TEMPLATES = [{
…
'OPTIONS': {
'context_processors': [
…
'app.context_processors.from_settings',
],
…
},
}]
Тепер, коли ви заходите в кабінет, ви побачите індикатор поточного середовища.
#3 Дайте вашому кабінету і'мя
Якщо ви адмініструєте декілька сайтів на Django, де кабінет виглядає однаково, можна ненароком схибити й зробити щось погане. Дайте вашому кабінету ім'я:
# urls.py
from django.contrib import admin
admin.site.site_header = 'Awesome Inc. Administration'
admin.site.site_title = 'Awesome Inc. Administration'
Результат:
Для більш гнучкого налаштування зазирніть в документацію.
#4 Розділіть кабінет адміністратора та основний сайт
Використовуючи одну й ту ж саму кодову базу, ви можете підняти два екземпляри вашого додатка — один лише для кабінету адміністратора, інший — для решти додатка.
Втілити це не так просто, як минулі поради, все залежить від вашої конфігурації (наприклад, використовуєте ви gunicorn чи uwsgi), тому я не буду вдаватися в деталі.
Але навіщо відділяти кабінет від основного сайту? Можливо, ви захочете:
-
Підняти кабінет адміністратора всередині VPN — якщо його використовують лише в вашій компанії (або взагалі ви сам), гарною ідеєю буде підняти його всередині VPN (якщо він є).
-
Видалити непотрібні функції — наприклад, кабінет використовує messages framework. Якщо ж основний сайт його не використовує — ви можете видалити це middleware. Іншим прикладом є механізм авторизації: якщо основний сайт виконаний в вигляді REST API з аутентифікацією за допомогою токенів, ви можете видалити купу конфігурацій шаблонів, middleware для сесій та інше, і звести весь процес взаємодії до циклу запит-відповідь.
-
Надійніша аутентифікація — якщо ви хочете підвищити безпеку вашого кабінету, ймовірно, ви захочете і змінити процес аутентифікації на більш надійний. При розділенні це зробити простіше.
Ми розділили їх лише в публічній стороні, код лишився той самий. Розподіл коду куди складніший, його складніше підняти на сервері та й переваг від цього ніяких немає.
#5 Додайте двофакторну аутентифікацію (2FA)
Двофакторна аутентифікація останнім часом набуває популярності, й не дивно. 2FA виконує процес аутентифікації за допомогою двох речей:
-
Щось, що ви знаєте, наприклад, пароль.
-
Щось, що ви маєте, наприклад, додаток на телефоні, що генерує випадкові паролі, що дійсні 30 секунд (наприклад, Authenticator by Google).
При першому вході в систему користувача попросять просканувати штрих-код за допомогою додатка на телефоні. Після цього додаток буде генерувати одноразові коди саме для цього сайту.
Зазвичай я не рекомендую сторонніх модулів, але нещодавно ми почали використовувати django-otp для реалізації 2FA і задоволені своїм вибором.
Встановити його дуже просто:
pip install django-otp
pip install qrcode
Та додайте до встановлених додатків та middleware:
# settings.py
INSTALLED_APPS = (
...
'django_otp',
'django_otp.plugins.otp_totp',
...
)
...
MIDDLEWARE = (
...
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django_otp.middleware.OTPMiddleware',
...
)
Назвіть видавця — це і'мя буде показано в додатку для аутентифікації, тому не пишіть сюди всілякі дурниці.
# settings.py
OTP_TOTP_ISSUER = 'Awesome Inc.'
Та, власне, додайте 2FA до кабінету адміністратора:
# urls.py
from django_otp.admin import OTPAdminSite
admin.site.__class__ = OTPAdminSite
Тепер вхід до нашого безпечного кабінету виглядає так:
Щоб створити нового користувача, створіть «TOTP Device» в кабінеті адміністратора. Після цього клікніть по QR-посиланню і ви побачите щось на зразок цього:
Лишилося лише просканувати його.
Ще немає коментарів