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

IP, brute force, брутфорс, 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.

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

Register model in the admin

from django.contrib import admin
from .models import TemporaryBanIp, TemporaryBanIpAdmin


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 .

class ELoginView(View):

    # source of get method

    def post(self, request):
        # get data of forms from request
        form = AuthenticationForm(request, data=request.POST)

        # get IP adress form request
        ip = get_client_ip(request)
        # We obtain or create a new entry for the IP, with which to enter a password for blocking
        obj, created = TemporaryBanIp.objects.get_or_create(
            defaults={
                'ip_address': ip,
                'time_unblock': timezone.now()
            },
            ip_address=ip
        )

        # if an IP is locked and unlocking time has not come
        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:
                # then open the page with the message blocking for 15 minutes at 3 and 6 failed login attempting to login
                return render_to_response('accounts/block_15_minutes.html', context=context)
            elif obj.attempts == 9:
                # or open the page about blocking for 24 hours, with 9 of failed login attempting to login
                return render_to_response('accounts/block_24_hours.html', context=context)
        elif obj.status is True and obj.time_unblock < timezone.now():
            # if the IP is blocked, but the release time has come, then unlock IP
            obj.status = False
            obj.save()

        # if the user entered the correct data, authorizing it, and remove the entry for IP blocking
        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:
            # otherwise count attempts to set the time and unlock and lock status 
            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)

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 .

10% refund of hotel reservation amount on Booking
10% refund of hotel reservation amount on Booking
We offer a link with a 10% return on the amount of the order when booking a hotel through Booking
Support the author Donate

Comments

Only authorized users can post comments.
Please, Log in or Sign up
Looking for a Job?
14,000.00 руб. - 40,000.00 руб.
Разработчик Qt
Annino, Moscow Oblast, Russia
5,000.00 руб. - 15,000.00 руб.
Дизайнер
Moskovskiy, Moscow, Russia
25,000.00 руб. - 30,000.00 руб.
Разработчик Qt/C++
Barnaul, Altai Krai, Russia

For registered users on the site there is a minimum amount of advertising

A
Aug. 22, 2019, 11:24 p.m.
Aleksandr73

Qt - Test 001. Signals and slots

  • Result:47points,
  • Rating points-6
Aug. 21, 2019, 10:23 a.m.
Andrej Ermoshin

C++ - Test 002. Constants

  • Result:58points,
  • Rating points-2
Aug. 21, 2019, 10:15 a.m.
Andrej Ermoshin

C++ - Test 001. The first program and data types

  • Result:86points,
  • Rating points6
Last comments
Aug. 19, 2019, 7:41 a.m.
Andrej Jankovich

это проблема дистрибутива, попробуйте установить через пакетный менеджер snap Суть проблемы: libQt5Core которая лежит в дистрибутиве требует версию glibc >= 2.25 у вас видимо …
b
Aug. 18, 2019, 6:09 a.m.
bbb116

cqtdeployer /home/aleks/CQtDeployer/bin/cqtdeployer: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.25' not found (required by /home/aleks/CQtDeployer/lib/libQt5Core.so.5) linux mint …
D
Aug. 17, 2019, 9:04 a.m.
Damir

github ChekableTView Правой групповая смена значения при перетаскивании левой как обычно.
Aug. 16, 2019, 1:03 p.m.
Evgenij Legotskoj

Потому, что в минуте 60 секунд
Aug. 16, 2019, 12:16 p.m.
Dmitrij

а почему делитель 60000, а не 1000?
Now discuss on the forum
Aug. 24, 2019, 7:21 a.m.
Evgenij Legotskoj

Не помню, давно уже с QML не работал, по-моему, обычно пишет в консоль, что не находит файл. В любом случае какую-то ошибку в консоль выкидывает. Но если честно, если у вас проект будет ак…
BG
Aug. 24, 2019, 4:27 a.m.
Brjus Gliff

Спасибо, вначале в документации было не понятно что к чему, теперь разобрался
I
Aug. 21, 2019, 8:36 a.m.
Intruder

Александр, мне не нужно перебирать. Вы говорите правильно, сначала я написал избыточный код просто не подумав. Задача такая, мне нужно просто переложить из QMap в атрибуты xml тега все, что там …
Aug. 21, 2019, 3:16 a.m.
nayk1982

Если Вы разрабатываете какую-то универсальную утилиту, которая вообще не привязана к логике, тогда как вариант: 1. Получить список таблиц через QSqlDatabase::tables 2. Для каждой табли…
EVILEG
About
Services
© EVILEG 2015-2019
Recommend hosting TIMEWEB