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 .