После того, как мы подменили страницу авторизации Django на свою собственную кастомизированную страницу авторизации , настал момент для использования данной подмены для целей улучшения безопасности сайта. Например, внедрение блокировки злоумышленника по IP при попытке подбора пароля.
Предлагаю такой вариант блокировки: при трех неудачных попытках ввода пароля IP блокируется на 15 минут, если такая блокировка на 15 минут происходит 3 раза, то IP блокируется на 24 часа.
Для реализации блокировки понадобится модель, в которой будет находится 4 поля:
- IP адрес;
- Количество попыток ввода пароля;
- Время разблокировки;
- Статус блокировки - True - если заблокирован, False - если не заблокирован.
Сразу покажу результат работы блокировок в админке сайта, за пару месяцев уже накопилась небольшая коллекция.
models.py
А теперь посмотрим, как будет выглядеть модель для временных блокировок от подбора пароля, а также, как настроить админку, чтобы таблица с блокировками выглядела так, как показано на рисунке выше.
from django.db import models from django.contrib import admin class TemporaryBanIp(models.Model): class Meta: db_table = "TemporaryBanIp" ip_address = models.GenericIPAddressField("IP адрес") attempts = models.IntegerField("Неудачных попыток", default=0) time_unblock = models.DateTimeField("Время разблокировки", blank=True) status = models.BooleanField("Статус блокировки", default=False) def __str__(self): return self.ip_address class TemporaryBanIpAdmin(admin.ModelAdmin): list_display = ('ip_address', 'status', 'attempts', 'time_unblock') search_fields = ('ip_address',)
admin.py
Регистрация модели в админке
from django.contrib import admin from .models import TemporaryBanIp, TemporaryBanIpAdmin admin.site.register(TemporaryBanIp, TemporaryBanIpAdmin)
views.py
Модифицируем метод post кастомизированной страницы авторизации из прошлой статьи. В данном коде также используется специальная функция для получения IP адреса из запроса .
class ELoginView(View): # код метода get def post(self, request): # забираем данные формы авторизации из запроса form = AuthenticationForm(request, data=request.POST) # забираем IP адрес из запроса ip = get_client_ip(request) # получаем или создаём новую запись об IP, с которого вводится пароль, на предмет блокировки obj, created = TemporaryBanIp.objects.get_or_create( defaults={ 'ip_address': ip, 'time_unblock': timezone.now() }, ip_address=ip ) # если IP заблокирован и время разблокировки не настало if obj.status is True and obj.time_unblock > timezone.now(): context = create_context_username_csrf(request) if obj.attempts == 3 or obj.attempts == 6: # то открываем страницу с сообщением о блокировки на 15 минут при 3 и 6 неудачных попытках входа return render_to_response('accounts/block_15_minutes.html', context=context) elif obj.attempts == 9: # или открываем страницу о блокировке на 24 часа, при 9 неудачных попытках входа return render_to_response('accounts/block_24_hours.html', context=context) elif obj.status is True and obj.time_unblock < timezone.now(): # если IP заблокирован, но время разблокировки настало, то разблокируем IP obj.status = False obj.save() # если пользователь ввёл верные данные, то авторизуем его и удаляем запись о блокировке IP if form.is_valid(): auth.login(request, form.get_user()) obj.delete() next = urlparse(get_next_url(request)).path if next == '/admin/login/' and request.user.is_staff: return redirect('/admin/') return redirect(next) else: # иначе считаем попытки и устанавливаем время разблокировки и статус блокировки obj.attempts += 1 if obj.attempts == 3 or obj.attempts == 6: obj.time_unblock = timezone.now() + timezone.timedelta(minutes=15) obj.status = True elif obj.attempts == 9: obj.time_unblock = timezone.now() + timezone.timedelta(1) obj.status = True elif obj.attempts > 9: obj.attempts = 1 obj.save() context = create_context_username_csrf(request) context['login_form'] = form return render_to_response('accounts/login.html', context=context)
Таким вот способом можно сделать довольно простое противодействие брутфорсу пароля для небольшого сайта на Django.
Для Django рекомендую VDS-сервера хостера Timeweb .