mirror of
https://github.com/swissmakers/fail2ban-ui.git
synced 2026-04-11 13:47:05 +02:00
Remove old - las 5 bans - from the socked query
This commit is contained in:
@@ -27,12 +27,10 @@
|
|||||||
"dashboard.table.new_last_hour": "Neu in letzter Stunde",
|
"dashboard.table.new_last_hour": "Neu in letzter Stunde",
|
||||||
"dashboard.table.banned_ips": "Gesperrte IPs (Entsperren)",
|
"dashboard.table.banned_ips": "Gesperrte IPs (Entsperren)",
|
||||||
"dashboard.no_jails": "Keine Jails gefunden.",
|
"dashboard.no_jails": "Keine Jails gefunden.",
|
||||||
"dashboard.last_bans": "Letzte 5 Sperrvorgänge",
|
|
||||||
"dashboard.table.time": "Zeit",
|
"dashboard.table.time": "Zeit",
|
||||||
"dashboard.table.jail": "Jail",
|
"dashboard.table.jail": "Jail",
|
||||||
"dashboard.table.ip": "IP",
|
"dashboard.table.ip": "IP",
|
||||||
"dashboard.table.log_line": "Logzeile",
|
"dashboard.table.log_line": "Logzeile",
|
||||||
"dashboard.no_recent_bans": "Keine aktuellen Sperrvorgänge gefunden.",
|
|
||||||
"dashboard.no_banned_ips": "Keine gesperrten IPs",
|
"dashboard.no_banned_ips": "Keine gesperrten IPs",
|
||||||
"dashboard.unban": "Entsperren",
|
"dashboard.unban": "Entsperren",
|
||||||
"logs.overview.title": "Interne Log-Übersicht",
|
"logs.overview.title": "Interne Log-Übersicht",
|
||||||
|
|||||||
@@ -27,12 +27,10 @@
|
|||||||
"dashboard.table.new_last_hour": "Neu in dr letschte Stund",
|
"dashboard.table.new_last_hour": "Neu in dr letschte Stund",
|
||||||
"dashboard.table.banned_ips": "G'sperrti IPs (Entsperre)",
|
"dashboard.table.banned_ips": "G'sperrti IPs (Entsperre)",
|
||||||
"dashboard.no_jails": "Kei Jails gfunde.",
|
"dashboard.no_jails": "Kei Jails gfunde.",
|
||||||
"dashboard.last_bans": "Letschti 5 Sperrvorgäng",
|
|
||||||
"dashboard.table.time": "Zyt",
|
"dashboard.table.time": "Zyt",
|
||||||
"dashboard.table.jail": "Jail",
|
"dashboard.table.jail": "Jail",
|
||||||
"dashboard.table.ip": "IP",
|
"dashboard.table.ip": "IP",
|
||||||
"dashboard.table.log_line": "Log-Zile",
|
"dashboard.table.log_line": "Log-Zile",
|
||||||
"dashboard.no_recent_bans": "Kei aktuelli Sperrvorgäng gfunde.",
|
|
||||||
"dashboard.no_banned_ips": "Kei g'sperrti IPs",
|
"dashboard.no_banned_ips": "Kei g'sperrti IPs",
|
||||||
"dashboard.unban": "Entsperre",
|
"dashboard.unban": "Entsperre",
|
||||||
"logs.overview.title": "Interni Log-Übersicht",
|
"logs.overview.title": "Interni Log-Übersicht",
|
||||||
|
|||||||
@@ -27,12 +27,10 @@
|
|||||||
"dashboard.table.new_last_hour": "New Last Hour",
|
"dashboard.table.new_last_hour": "New Last Hour",
|
||||||
"dashboard.table.banned_ips": "Banned IPs (Unban)",
|
"dashboard.table.banned_ips": "Banned IPs (Unban)",
|
||||||
"dashboard.no_jails": "No jails found.",
|
"dashboard.no_jails": "No jails found.",
|
||||||
"dashboard.last_bans": "Last 5 Ban Events",
|
|
||||||
"dashboard.table.time": "Time",
|
"dashboard.table.time": "Time",
|
||||||
"dashboard.table.jail": "Jail",
|
"dashboard.table.jail": "Jail",
|
||||||
"dashboard.table.ip": "IP",
|
"dashboard.table.ip": "IP",
|
||||||
"dashboard.table.log_line": "Log Line",
|
"dashboard.table.log_line": "Log Line",
|
||||||
"dashboard.no_recent_bans": "No recent bans found.",
|
|
||||||
"dashboard.no_banned_ips": "No banned IPs",
|
"dashboard.no_banned_ips": "No banned IPs",
|
||||||
"dashboard.unban": "Unban",
|
"dashboard.unban": "Unban",
|
||||||
"logs.overview.title": "Internal Log Overview",
|
"logs.overview.title": "Internal Log Overview",
|
||||||
|
|||||||
@@ -27,12 +27,10 @@
|
|||||||
"dashboard.table.new_last_hour": "Nuevas en la última hora",
|
"dashboard.table.new_last_hour": "Nuevas en la última hora",
|
||||||
"dashboard.table.banned_ips": "IPs bloqueadas (Desbloquear)",
|
"dashboard.table.banned_ips": "IPs bloqueadas (Desbloquear)",
|
||||||
"dashboard.no_jails": "No se encontraron jails.",
|
"dashboard.no_jails": "No se encontraron jails.",
|
||||||
"dashboard.last_bans": "Últimos 5 eventos de bloqueo",
|
|
||||||
"dashboard.table.time": "Hora",
|
"dashboard.table.time": "Hora",
|
||||||
"dashboard.table.jail": "Jail",
|
"dashboard.table.jail": "Jail",
|
||||||
"dashboard.table.ip": "IP",
|
"dashboard.table.ip": "IP",
|
||||||
"dashboard.table.log_line": "Línea de log",
|
"dashboard.table.log_line": "Línea de log",
|
||||||
"dashboard.no_recent_bans": "No se encontraron bloqueos recientes.",
|
|
||||||
"dashboard.no_banned_ips": "No hay IP bloqueadas",
|
"dashboard.no_banned_ips": "No hay IP bloqueadas",
|
||||||
"dashboard.unban": "Desbloquear",
|
"dashboard.unban": "Desbloquear",
|
||||||
"logs.overview.title": "Resumen interno de registros",
|
"logs.overview.title": "Resumen interno de registros",
|
||||||
|
|||||||
@@ -27,12 +27,10 @@
|
|||||||
"dashboard.table.new_last_hour": "Nouveaux dans la dernière heure",
|
"dashboard.table.new_last_hour": "Nouveaux dans la dernière heure",
|
||||||
"dashboard.table.banned_ips": "IPs bloquées (Débloquer)",
|
"dashboard.table.banned_ips": "IPs bloquées (Débloquer)",
|
||||||
"dashboard.no_jails": "Aucun jail trouvé.",
|
"dashboard.no_jails": "Aucun jail trouvé.",
|
||||||
"dashboard.last_bans": "5 derniers événements de blocage",
|
|
||||||
"dashboard.table.time": "Heure",
|
"dashboard.table.time": "Heure",
|
||||||
"dashboard.table.jail": "Jail",
|
"dashboard.table.jail": "Jail",
|
||||||
"dashboard.table.ip": "IP",
|
"dashboard.table.ip": "IP",
|
||||||
"dashboard.table.log_line": "Ligne de log",
|
"dashboard.table.log_line": "Ligne de log",
|
||||||
"dashboard.no_recent_bans": "Aucun blocage récent trouvé.",
|
|
||||||
"dashboard.no_banned_ips": "Aucune IP bloquée",
|
"dashboard.no_banned_ips": "Aucune IP bloquée",
|
||||||
"dashboard.unban": "Débloquer",
|
"dashboard.unban": "Débloquer",
|
||||||
"logs.overview.title": "Vue d'ensemble interne des journaux",
|
"logs.overview.title": "Vue d'ensemble interne des journaux",
|
||||||
|
|||||||
@@ -27,12 +27,10 @@
|
|||||||
"dashboard.table.new_last_hour": "Nuove nell'ultima ora",
|
"dashboard.table.new_last_hour": "Nuove nell'ultima ora",
|
||||||
"dashboard.table.banned_ips": "IP bloccate (Sblocca)",
|
"dashboard.table.banned_ips": "IP bloccate (Sblocca)",
|
||||||
"dashboard.no_jails": "Nessun jail trovato.",
|
"dashboard.no_jails": "Nessun jail trovato.",
|
||||||
"dashboard.last_bans": "Ultimi 5 eventi di blocco",
|
|
||||||
"dashboard.table.time": "Ora",
|
"dashboard.table.time": "Ora",
|
||||||
"dashboard.table.jail": "Jail",
|
"dashboard.table.jail": "Jail",
|
||||||
"dashboard.table.ip": "IP",
|
"dashboard.table.ip": "IP",
|
||||||
"dashboard.table.log_line": "Riga di log",
|
"dashboard.table.log_line": "Riga di log",
|
||||||
"dashboard.no_recent_bans": "Nessun blocco recente trovato.",
|
|
||||||
"dashboard.no_banned_ips": "Nessuna IP bloccata",
|
"dashboard.no_banned_ips": "Nessuna IP bloccata",
|
||||||
"dashboard.unban": "Sblocca",
|
"dashboard.unban": "Sblocca",
|
||||||
"logs.overview.title": "Panoramica interna dei log",
|
"logs.overview.title": "Panoramica interna dei log",
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ import (
|
|||||||
// SummaryResponse is what we return from /api/summary
|
// SummaryResponse is what we return from /api/summary
|
||||||
type SummaryResponse struct {
|
type SummaryResponse struct {
|
||||||
Jails []fail2ban.JailInfo `json:"jails"`
|
Jails []fail2ban.JailInfo `json:"jails"`
|
||||||
LastBans []fail2ban.BanEvent `json:"lastBans"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func resolveConnector(c *gin.Context) (fail2ban.Connector, error) {
|
func resolveConnector(c *gin.Context) (fail2ban.Connector, error) {
|
||||||
@@ -89,7 +88,6 @@ func resolveServerForNotification(serverID, hostname string) (config.Fail2banSer
|
|||||||
|
|
||||||
// SummaryHandler returns a JSON summary of all jails, including
|
// SummaryHandler returns a JSON summary of all jails, including
|
||||||
// number of banned IPs, how many are new in the last hour, etc.
|
// number of banned IPs, how many are new in the last hour, etc.
|
||||||
// and the last 5 overall ban events from the log.
|
|
||||||
func SummaryHandler(c *gin.Context) {
|
func SummaryHandler(c *gin.Context) {
|
||||||
conn, err := resolveConnector(c)
|
conn, err := resolveConnector(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -103,15 +101,8 @@ func SummaryHandler(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
lastBans, err := conn.FetchBanEvents(c.Request.Context(), 5)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("warning: failed to fetch ban events for summary: %v", err)
|
|
||||||
lastBans = []fail2ban.BanEvent{}
|
|
||||||
}
|
|
||||||
|
|
||||||
resp := SummaryResponse{
|
resp := SummaryResponse{
|
||||||
Jails: jailInfos,
|
Jails: jailInfos,
|
||||||
LastBans: lastBans,
|
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, resp)
|
c.JSON(http.StatusOK, resp)
|
||||||
}
|
}
|
||||||
@@ -504,16 +495,6 @@ func shouldAlertForCountry(country string, alertCountries []string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func sortByTimeDesc(events []fail2ban.BanEvent) {
|
|
||||||
for i := 0; i < len(events); i++ {
|
|
||||||
for j := i + 1; j < len(events); j++ {
|
|
||||||
if events[j].Time.After(events[i].Time) {
|
|
||||||
events[i], events[j] = events[j], events[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// IndexHandler serves the HTML page
|
// IndexHandler serves the HTML page
|
||||||
func IndexHandler(c *gin.Context) {
|
func IndexHandler(c *gin.Context) {
|
||||||
c.HTML(http.StatusOK, "index.html", gin.H{
|
c.HTML(http.StatusOK, "index.html", gin.H{
|
||||||
|
|||||||
@@ -1190,7 +1190,14 @@
|
|||||||
if (isNaN(date.getTime())) {
|
if (isNaN(date.getTime())) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
return date.toLocaleString();
|
// Format as "2025.11.12, 21:21:52"
|
||||||
|
var year = date.getFullYear();
|
||||||
|
var month = String(date.getMonth() + 1).padStart(2, '0');
|
||||||
|
var day = String(date.getDate()).padStart(2, '0');
|
||||||
|
var hours = String(date.getHours()).padStart(2, '0');
|
||||||
|
var minutes = String(date.getMinutes()).padStart(2, '0');
|
||||||
|
var seconds = String(date.getSeconds()).padStart(2, '0');
|
||||||
|
return year + '.' + month + '.' + day + ', ' + hours + ':' + minutes + ':' + seconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
function totalStoredBans() {
|
function totalStoredBans() {
|
||||||
@@ -1316,38 +1323,6 @@
|
|||||||
html += '</div>';
|
html += '</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (summary.lastBans) {
|
|
||||||
html += '<div class="mt-6">';
|
|
||||||
html += ' <h3 class="text-lg font-medium text-gray-900 mb-4" data-i18n="dashboard.last_bans">Last 5 Ban Events</h3>';
|
|
||||||
if (!summary.lastBans.length) {
|
|
||||||
html += '<p class="text-gray-500" data-i18n="dashboard.no_recent_bans">No recent bans found.</p>';
|
|
||||||
} else {
|
|
||||||
html += ''
|
|
||||||
+ '<div class="overflow-x-auto">'
|
|
||||||
+ ' <table class="min-w-full divide-y divide-gray-200 text-sm sm:text-base">'
|
|
||||||
+ ' <thead class="bg-gray-50">'
|
|
||||||
+ ' <tr>'
|
|
||||||
+ ' <th class="px-2 py-1 sm:px-6 sm:py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider" data-i18n="dashboard.table.time">Time</th>'
|
|
||||||
+ ' <th class="hidden sm:table-cell px-2 py-1 sm:px-6 sm:py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider" data-i18n="dashboard.table.jail">Jail</th>'
|
|
||||||
+ ' <th class="hidden sm:table-cell px-2 py-1 sm:px-6 sm:py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider" data-i18n="dashboard.table.ip">IP</th>'
|
|
||||||
+ ' <th class="px-2 py-1 sm:px-6 sm:py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider" data-i18n="dashboard.table.log_line">Details</th>'
|
|
||||||
+ ' </tr>'
|
|
||||||
+ ' </thead>'
|
|
||||||
+ ' <tbody class="bg-white divide-y divide-gray-200">';
|
|
||||||
summary.lastBans.forEach(function(event) {
|
|
||||||
html += ''
|
|
||||||
+ '<tr class="hover:bg-gray-50">'
|
|
||||||
+ ' <td class="px-2 py-1 sm:px-6 sm:py-4 whitespace-normal break-words">' + escapeHtml(event.Time || '') + '</td>'
|
|
||||||
+ ' <td class="hidden sm:table-cell px-2 py-1 sm:px-6 sm:py-4 whitespace-normal break-words">' + escapeHtml(event.Jail || '') + '</td>'
|
|
||||||
+ ' <td class="hidden sm:table-cell px-2 py-1 sm:px-6 sm:py-4 whitespace-normal break-words">' + escapeHtml(event.IP || '') + '</td>'
|
|
||||||
+ ' <td class="px-2 py-1 sm:px-6 sm:py-4 whitespace-normal break-words">' + escapeHtml(event.LogLine || '') + '</td>'
|
|
||||||
+ '</tr>';
|
|
||||||
});
|
|
||||||
html += ' </tbody></table></div>';
|
|
||||||
}
|
|
||||||
html += '</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
html += '</div>'; // close overview card
|
html += '</div>'; // close overview card
|
||||||
|
|
||||||
html += renderLogOverview();
|
html += renderLogOverview();
|
||||||
|
|||||||
@@ -719,37 +719,6 @@
|
|||||||
html += '</div></fieldset>';
|
html += '</div></fieldset>';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Last 5 bans
|
|
||||||
html += '<fieldset class="border p-3 rounded mb-4">';
|
|
||||||
html += ' <legend class="w-auto px-2" data-i18n="dashboard.last_bans">Last 5 Ban Events</legend>';
|
|
||||||
if (!data.lastBans || data.lastBans.length === 0) {
|
|
||||||
html += '<p data-i18n="dashboard.no_recent_bans">No recent bans found.</p>';
|
|
||||||
} else {
|
|
||||||
html += ''
|
|
||||||
+ '<div class="table-responsive">'
|
|
||||||
+ '<table class="table table-bordered">'
|
|
||||||
+ ' <thead>'
|
|
||||||
+ ' <tr>'
|
|
||||||
+ ' <th data-i18n="dashboard.table.time">Time</th>'
|
|
||||||
+ ' <th data-i18n="dashboard.table.jail">Jail</th>'
|
|
||||||
+ ' <th data-i18n="dashboard.table.ip">IP</th>'
|
|
||||||
+ ' <th data-i18n="dashboard.table.log_line">Log Line</th>'
|
|
||||||
+ ' </tr>'
|
|
||||||
+ ' </thead>'
|
|
||||||
+ ' <tbody></div>';
|
|
||||||
|
|
||||||
data.lastBans.forEach(function(e) {
|
|
||||||
html += ''
|
|
||||||
+ '<tr>'
|
|
||||||
+ ' <td>' + e.Time + '</td>'
|
|
||||||
+ ' <td>' + e.Jail + '</td>'
|
|
||||||
+ ' <td>' + e.IP + '</td>'
|
|
||||||
+ ' <td>' + e.LogLine + '</td>'
|
|
||||||
+ '</tr>';
|
|
||||||
});
|
|
||||||
|
|
||||||
html += '</tbody></table></fieldset>';
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById('dashboard').innerHTML = html;
|
document.getElementById('dashboard').innerHTML = html;
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 870 KiB After Width: | Height: | Size: 924 KiB |
Reference in New Issue
Block a user