- 1. Modelle.py
- 2. admin.py
- 3. views.py
Nachdem wir die Django-Anmeldeseite durch unsere eigene benutzerdefinierte Anmeldeseite ersetzt haben, ist es an der Zeit, diese Ersetzung zur Verbesserung der Site-Sicherheit zu verwenden. Zum Beispiel die Einführung, einen Angreifer per IP zu blockieren, wenn er versucht, ein Passwort zu erraten.
Ich schlage diese Sperroption vor: Bei drei erfolglosen Versuchen, ein Passwort einzugeben, wird die IP für 15 Minuten gesperrt. Wenn eine solche Sperrung für 15 Minuten dreimal auftritt, wird die IP für 24 Stunden gesperrt.
Um die Sperre zu implementieren, benötigen Sie ein Modell, das 4 Felder enthält:
- IP Adresse;
- Anzahl der Passworteingabeversuche;
- Entsperrzeit;
- Blockierungsstatus - True - wenn blockiert, False - wenn nicht blockiert.
Ich werde das Ergebnis der Blockierungsarbeit sofort im Site-Admin-Panel zeigen, seit ein paar Monaten hat sich bereits eine kleine Sammlung angesammelt.
Modelle.py
Sehen wir uns nun an, wie das Modell für temporäre Sperren zum Erraten von Passwörtern aussehen wird und wie das Admin-Panel so konfiguriert wird, dass die Tabelle mit Sperren wie in der Abbildung oben aussieht.
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
Registrierung des Modells im Admin-Panel
from django.contrib import admin from .models import TemporaryBanIp, TemporaryBanIpAdmin admin.site.register(TemporaryBanIp, TemporaryBanIpAdmin)
views.py
Lassen Sie uns die Methode post benutzerdefinierte Anmeldeseite aus dem vorherigen Artikel ändern. Dieser Code verwendet auch eine spezielle Funktion, um eine IP-Adresse aus einer Anfrage zu erhalten .
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)
Auf diese Weise können Sie eine relativ einfache Brute-Force-Gegenmaßnahme für Passwörter für eine kleine Django-Site durchführen.
Für Django empfehle ich Timeweb-Hoster VDS-Server .