115 Zeilen
5.3 KiB
HTML
115 Zeilen
5.3 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title>Gesperrte IPs - Admin Panel</title>
|
||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||
</head>
|
||
<body class="bg-light">
|
||
<nav class="navbar navbar-dark bg-dark">
|
||
<div class="container">
|
||
<span class="navbar-brand">🎛️ Lizenzverwaltung</span>
|
||
<div class="d-flex align-items-center">
|
||
<span class="text-white me-3">Angemeldet als: {{ username }}</span>
|
||
<a href="/logout" class="btn btn-outline-light btn-sm">Abmelden</a>
|
||
</div>
|
||
</div>
|
||
</nav>
|
||
|
||
<div class="container py-4">
|
||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||
<h1>🔒 Gesperrte IPs</h1>
|
||
<div>
|
||
<a href="/" class="btn btn-secondary">← Dashboard</a>
|
||
<a href="/audit" class="btn btn-secondary">📋 Audit-Log</a>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<h5 class="mb-0">IP-Sperrverwaltung</h5>
|
||
</div>
|
||
<div class="card-body">
|
||
{% if blocked_ips %}
|
||
<div class="table-responsive">
|
||
<table class="table table-hover">
|
||
<thead>
|
||
<tr>
|
||
<th>IP-Adresse</th>
|
||
<th>Versuche</th>
|
||
<th>Erster Versuch</th>
|
||
<th>Letzter Versuch</th>
|
||
<th>Gesperrt bis</th>
|
||
<th>Letzter User</th>
|
||
<th>Letzte Meldung</th>
|
||
<th>Status</th>
|
||
<th>Aktionen</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for ip in blocked_ips %}
|
||
<tr class="{% if ip.is_active %}table-danger{% else %}table-secondary{% endif %}">
|
||
<td><code>{{ ip.ip_address }}</code></td>
|
||
<td><span class="badge bg-danger">{{ ip.attempt_count }}</span></td>
|
||
<td>{{ ip.first_attempt }}</td>
|
||
<td>{{ ip.last_attempt }}</td>
|
||
<td>{{ ip.blocked_until }}</td>
|
||
<td>{{ ip.last_username or '-' }}</td>
|
||
<td><strong>{{ ip.last_error or '-' }}</strong></td>
|
||
<td>
|
||
{% if ip.is_active %}
|
||
<span class="badge bg-danger">GESPERRT</span>
|
||
{% else %}
|
||
<span class="badge bg-secondary">ABGELAUFEN</span>
|
||
{% endif %}
|
||
</td>
|
||
<td>
|
||
<div class="btn-group btn-group-sm" role="group">
|
||
{% if ip.is_active %}
|
||
<form method="post" action="/security/unblock-ip" class="d-inline">
|
||
<input type="hidden" name="ip_address" value="{{ ip.ip_address }}">
|
||
<button type="submit" class="btn btn-success"
|
||
onclick="return confirm('IP {{ ip.ip_address }} wirklich entsperren?')">
|
||
🔓 Entsperren
|
||
</button>
|
||
</form>
|
||
{% endif %}
|
||
<form method="post" action="/security/clear-attempts" class="d-inline ms-1">
|
||
<input type="hidden" name="ip_address" value="{{ ip.ip_address }}">
|
||
<button type="submit" class="btn btn-warning"
|
||
onclick="return confirm('Alle Versuche für IP {{ ip.ip_address }} zurücksetzen?')">
|
||
🗑️ Reset
|
||
</button>
|
||
</form>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
{% else %}
|
||
<div class="alert alert-info">
|
||
<strong>Keine gesperrten IPs vorhanden.</strong>
|
||
Das System läuft ohne Sicherheitsvorfälle.
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card mt-4">
|
||
<div class="card-body">
|
||
<h5 class="card-title">ℹ️ Informationen</h5>
|
||
<ul class="mb-0">
|
||
<li>IPs werden nach <strong>{{ 5 }} fehlgeschlagenen Login-Versuchen</strong> für <strong>24 Stunden</strong> gesperrt.</li>
|
||
<li>Nach <strong>2 Versuchen</strong> wird ein CAPTCHA angezeigt.</li>
|
||
<li>Bei <strong>5 Versuchen</strong> wird eine E-Mail-Benachrichtigung gesendet (wenn aktiviert).</li>
|
||
<li>Gesperrte IPs können manuell entsperrt werden.</li>
|
||
<li>Die Fehlermeldungen werden zufällig ausgewählt für zusätzliche Verwirrung.</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</body>
|
||
</html> |