Evgenii Legotckoi
Jan. 9, 2017, 8:45 p.m.

Django - Tutorial 018. Hackers blocking IP when attempting to password guessing on Django

After we replaced the login page Django on his own customized login page , the time has come to use this substitution for the purpose of improving the security of the site. For example, the introduction of an IP attacker blocking when attempting to password guessing.

I propose such blocking variant: the three failed attempting to enter a password IP blocked for 15 minutes, if such blocking occurs for 15 minutes 3 times, then blocked IP for 24 hours.

To implement the blocking we required model, which will be located 4 fields:

  • IP address;
  • The number of password attempts;
  • Unblock time;
  • Blocking Status - True - if blocked, False - if not blocked.

Just show the result of blockages in the admin site for a couple of months already accumulated a small collection.


models.py

Now let's see how the model will look for temporary blocking of password cracking, as well as how to set up the admin panel to table locks look as shown in the figure above.

  1. from django.db import models
  2. from django.contrib import admin
  3.  
  4.  
  5. class TemporaryBanIp(models.Model):
  6. class Meta:
  7. db_table = "TemporaryBanIp"
  8.  
  9. ip_address = models.GenericIPAddressField("IP адрес")
  10. attempts = models.IntegerField("Неудачных попыток", default=0)
  11. time_unblock = models.DateTimeField("Время разблокировки", blank=True)
  12. status = models.BooleanField("Статус блокировки", default=False)
  13.  
  14. def __str__(self):
  15. return self.ip_address
  16.  
  17.  
  18. class TemporaryBanIpAdmin(admin.ModelAdmin):
  19. list_display = ('ip_address', 'status', 'attempts', 'time_unblock')
  20. search_fields = ('ip_address',)

admin.py

Register model in the admin

  1. from django.contrib import admin
  2. from .models import TemporaryBanIp, TemporaryBanIpAdmin
  3.  
  4.  
  5. admin.site.register(TemporaryBanIp, TemporaryBanIpAdmin)

views.py

Modify the post method of customized login page from the last article. This code also uses a special function to obtain the IP address of the request .

  1. class ELoginView(View):
  2.  
  3. # source of get method
  4.  
  5. def post(self, request):
  6. # get data of forms from request
  7. form = AuthenticationForm(request, data=request.POST)
  8.  
  9. # get IP adress form request
  10. ip = get_client_ip(request)
  11. # We obtain or create a new entry for the IP, with which to enter a password for blocking
  12. obj, created = TemporaryBanIp.objects.get_or_create(
  13. defaults={
  14. 'ip_address': ip,
  15. 'time_unblock': timezone.now()
  16. },
  17. ip_address=ip
  18. )
  19.  
  20. # if an IP is locked and unlocking time has not come
  21. if obj.status is True and obj.time_unblock > timezone.now():
  22. context = create_context_username_csrf(request)
  23. if obj.attempts == 3 or obj.attempts == 6:
  24. # then open the page with the message blocking for 15 minutes at 3 and 6 failed login attempting to login
  25. return render_to_response('accounts/block_15_minutes.html', context=context)
  26. elif obj.attempts == 9:
  27. # or open the page about blocking for 24 hours, with 9 of failed login attempting to login
  28. return render_to_response('accounts/block_24_hours.html', context=context)
  29. elif obj.status is True and obj.time_unblock < timezone.now():
  30. # if the IP is blocked, but the release time has come, then unlock IP
  31. obj.status = False
  32. obj.save()
  33.  
  34. # if the user entered the correct data, authorizing it, and remove the entry for IP blocking
  35. if form.is_valid():
  36. auth.login(request, form.get_user())
  37. obj.delete()
  38.  
  39. next = urlparse(get_next_url(request)).path
  40. if next == '/admin/login/' and request.user.is_staff:
  41. return redirect('/admin/')
  42. return redirect(next)
  43. else:
  44. # otherwise count attempts to set the time and unlock and lock status
  45. obj.attempts += 1
  46. if obj.attempts == 3 or obj.attempts == 6:
  47. obj.time_unblock = timezone.now() + timezone.timedelta(minutes=15)
  48. obj.status = True
  49. elif obj.attempts == 9:
  50. obj.time_unblock = timezone.now() + timezone.timedelta(1)
  51. obj.status = True
  52. elif obj.attempts > 9:
  53. obj.attempts = 1
  54. obj.save()
  55.  
  56. context = create_context_username_csrf(request)
  57. context['login_form'] = form
  58.  
  59. return render_to_response('accounts/login.html', context=context)

So here's a way you can make a pretty simple opposition to brute force the password for a small site on Django.

For Django I recommend VDS-server of Timeweb hoster .

Do you like it? Share on social networks!

Comments

Only authorized users can post comments.
Please, Log in or Sign up
  • Last comments
  • AK
    April 1, 2025, 11:41 a.m.
    Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
  • Evgenii Legotckoi
    March 9, 2025, 9:02 p.m.
    К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
  • VP
    March 9, 2025, 4:14 p.m.
    Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…
  • ИМ
    Nov. 22, 2024, 9:51 p.m.
    Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
  • Evgenii Legotckoi
    Oct. 31, 2024, 11:37 p.m.
    Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup