mirror of
https://github.com/swissmakers/fail2ban-ui.git
synced 2026-04-17 05:53:15 +02:00
Implemented a real-time console log streaming via WebSocket for debugging purposes. Users can enable console output in settings to view application logs directly in the web interface.
This commit is contained in:
@@ -82,6 +82,9 @@ type AppSettings struct {
|
||||
// Email alert preferences
|
||||
EmailAlertsForBans bool `json:"emailAlertsForBans"` // Enable email alerts for ban events (default: true)
|
||||
EmailAlertsForUnbans bool `json:"emailAlertsForUnbans"` // Enable email alerts for unban events (default: false)
|
||||
|
||||
// Console output preferences
|
||||
ConsoleOutput bool `json:"consoleOutput"` // Enable console output in web UI (default: false)
|
||||
}
|
||||
|
||||
type AdvancedActionsConfig struct {
|
||||
@@ -425,6 +428,7 @@ func applyAppSettingsRecordLocked(rec storage.AppSettingsRecord) {
|
||||
currentSettings.CallbackSecret = rec.CallbackSecret
|
||||
currentSettings.EmailAlertsForBans = rec.EmailAlertsForBans
|
||||
currentSettings.EmailAlertsForUnbans = rec.EmailAlertsForUnbans
|
||||
currentSettings.ConsoleOutput = rec.ConsoleOutput
|
||||
}
|
||||
|
||||
func applyServerRecordsLocked(records []storage.ServerRecord) {
|
||||
@@ -511,6 +515,8 @@ func toAppSettingsRecordLocked() (storage.AppSettingsRecord, error) {
|
||||
GeoIPProvider: currentSettings.GeoIPProvider,
|
||||
GeoIPDatabasePath: currentSettings.GeoIPDatabasePath,
|
||||
MaxLogLines: currentSettings.MaxLogLines,
|
||||
// Console output settings
|
||||
ConsoleOutput: currentSettings.ConsoleOutput,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -1529,9 +1535,31 @@ func UpdateSettings(new AppSettings) (AppSettings, error) {
|
||||
}
|
||||
DebugLog("New settings applied: %v", currentSettings) // Log settings applied
|
||||
|
||||
// Update console log enabled state if it changed
|
||||
if old.ConsoleOutput != new.ConsoleOutput {
|
||||
// Import web package to update console log state
|
||||
// We'll handle this via a callback or direct call
|
||||
updateConsoleLogState(new.ConsoleOutput)
|
||||
}
|
||||
|
||||
if err := persistAllLocked(); err != nil {
|
||||
fmt.Println("Error saving settings:", err)
|
||||
return currentSettings, err
|
||||
}
|
||||
return currentSettings, nil
|
||||
}
|
||||
|
||||
// updateConsoleLogState updates the console log writer enabled state
|
||||
// This is called from UpdateSettings when console output setting changes
|
||||
var updateConsoleLogStateFunc func(bool)
|
||||
|
||||
// SetUpdateConsoleLogStateFunc sets the callback function to update console log state
|
||||
func SetUpdateConsoleLogStateFunc(fn func(bool)) {
|
||||
updateConsoleLogStateFunc = fn
|
||||
}
|
||||
|
||||
func updateConsoleLogState(enabled bool) {
|
||||
if updateConsoleLogStateFunc != nil {
|
||||
updateConsoleLogStateFunc(enabled)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +115,10 @@
|
||||
"settings.port_env_hint": "Um den Port über die Weboberfläche zu ändern, entfernen Sie die PORT-Umgebungsvariable und starten Sie den Container neu.",
|
||||
"settings.port_restart_hint": "⚠️ Port-Änderungen erfordern einen Neustart des Containers, um wirksam zu werden.",
|
||||
"settings.enable_debug": "Debug-Protokoll aktivieren",
|
||||
"settings.enable_console": "Konsolenausgabe aktivieren",
|
||||
"settings.console.title": "Konsolenausgabe",
|
||||
"settings.console.clear": "Löschen",
|
||||
"settings.console.save_hint": "Bitte speichern Sie zuerst Ihre Einstellungen, bevor hier Logs angezeigt werden.",
|
||||
"settings.alert": "Alarm-Einstellungen",
|
||||
"settings.callback_url": "Fail2ban Callback-URL",
|
||||
"settings.callback_url_placeholder": "http://127.0.0.1:8080",
|
||||
|
||||
@@ -115,6 +115,10 @@
|
||||
"settings.port_env_hint": "Um de Port über d Weboberflächi z ändere, entferne d PORT-Umgebigsvariable und start de Container neu.",
|
||||
"settings.port_restart_hint": "⚠️ Port-Änderige erfordere ä Neustart vom Container, zum wirksam z werde.",
|
||||
"settings.enable_debug": "Debug-Modus aktivierä",
|
||||
"settings.enable_console": "Konsolenusgab aktivierä",
|
||||
"settings.console.title": "Konsolenusgab",
|
||||
"settings.console.clear": "Löschä",
|
||||
"settings.console.save_hint": "Bitte speichere zerscht dini Istellige, bevor hiä Logs azeigt wärde.",
|
||||
"settings.alert": "Alarm-Istellige",
|
||||
"settings.callback_url": "Fail2ban Callback-URL",
|
||||
"settings.callback_url_placeholder": "http://127.0.0.1:8080",
|
||||
|
||||
@@ -115,6 +115,10 @@
|
||||
"settings.port_env_hint": "To change the port via Web UI, remove the PORT environment variable and restart the container.",
|
||||
"settings.port_restart_hint": "⚠️ Port changes require a container restart to take effect.",
|
||||
"settings.enable_debug": "Enable Debug Log",
|
||||
"settings.enable_console": "Enable Console Output",
|
||||
"settings.console.title": "Console Output",
|
||||
"settings.console.clear": "Clear",
|
||||
"settings.console.save_hint": "Please save your settings first before logs will be displayed here.",
|
||||
"settings.alert": "Alert Settings",
|
||||
"settings.callback_url": "Fail2ban Callback URL",
|
||||
"settings.callback_url_placeholder": "http://127.0.0.1:8080",
|
||||
|
||||
@@ -115,6 +115,10 @@
|
||||
"settings.port_env_hint": "Para cambiar el puerto mediante la interfaz web, elimine la variable de entorno PORT y reinicie el contenedor.",
|
||||
"settings.port_restart_hint": "⚠️ Los cambios de puerto requieren un reinicio del contenedor para surtir efecto.",
|
||||
"settings.enable_debug": "Habilitar el modo de depuración",
|
||||
"settings.enable_console": "Habilitar salida de consola",
|
||||
"settings.console.title": "Salida de consola",
|
||||
"settings.console.clear": "Limpiar",
|
||||
"settings.console.save_hint": "Por favor, guarde primero su configuración antes de que se muestren los registros aquí.",
|
||||
"settings.alert": "Configuración de alertas",
|
||||
"settings.callback_url": "URL de retorno de Fail2ban",
|
||||
"settings.callback_url_placeholder": "http://127.0.0.1:8080",
|
||||
|
||||
@@ -115,6 +115,10 @@
|
||||
"settings.port_env_hint": "Pour modifier le port via l'interface Web, supprimez la variable d'environnement PORT et redémarrez le conteneur.",
|
||||
"settings.port_restart_hint": "⚠️ Les modifications du port nécessitent un redémarrage du conteneur pour prendre effet.",
|
||||
"settings.enable_debug": "Activer le mode débogage",
|
||||
"settings.enable_console": "Activer la sortie console",
|
||||
"settings.console.title": "Sortie console",
|
||||
"settings.console.clear": "Effacer",
|
||||
"settings.console.save_hint": "Veuillez d'abord enregistrer vos paramètres avant que les journaux ne s'affichent ici.",
|
||||
"settings.alert": "Paramètres d'alerte",
|
||||
"settings.callback_url": "URL de rappel Fail2ban",
|
||||
"settings.callback_url_placeholder": "http://127.0.0.1:8080",
|
||||
|
||||
@@ -115,6 +115,10 @@
|
||||
"settings.port_env_hint": "Per modificare la porta tramite l'interfaccia Web, rimuovere la variabile d'ambiente PORT e riavviare il contenitore.",
|
||||
"settings.port_restart_hint": "⚠️ Le modifiche alla porta richiedono un riavvio del contenitore per avere effetto.",
|
||||
"settings.enable_debug": "Abilita debug",
|
||||
"settings.enable_console": "Abilita output console",
|
||||
"settings.console.title": "Output console",
|
||||
"settings.console.clear": "Pulisci",
|
||||
"settings.console.save_hint": "Si prega di salvare prima le impostazioni prima che i log vengano visualizzati qui.",
|
||||
"settings.alert": "Impostazioni di allarme",
|
||||
"settings.callback_url": "URL di callback Fail2ban",
|
||||
"settings.callback_url_placeholder": "http://127.0.0.1:8080",
|
||||
|
||||
@@ -60,6 +60,8 @@ type AppSettingsRecord struct {
|
||||
AlertCountriesJSON string
|
||||
EmailAlertsForBans bool
|
||||
EmailAlertsForUnbans bool
|
||||
// Console output settings
|
||||
ConsoleOutput bool
|
||||
// SMTP settings
|
||||
SMTPHost string
|
||||
SMTPPort int
|
||||
@@ -190,17 +192,17 @@ func GetAppSettings(ctx context.Context) (AppSettingsRecord, bool, error) {
|
||||
}
|
||||
|
||||
row := db.QueryRowContext(ctx, `
|
||||
SELECT language, port, debug, restart_needed, callback_url, callback_secret, alert_countries, email_alerts_for_bans, email_alerts_for_unbans, smtp_host, smtp_port, smtp_username, smtp_password, smtp_from, smtp_use_tls, bantime_increment, default_jail_enable, ignore_ip, bantime, findtime, maxretry, destemail, banaction, banaction_allports, advanced_actions, geoip_provider, geoip_database_path, max_log_lines
|
||||
SELECT language, port, debug, restart_needed, callback_url, callback_secret, alert_countries, email_alerts_for_bans, email_alerts_for_unbans, smtp_host, smtp_port, smtp_username, smtp_password, smtp_from, smtp_use_tls, bantime_increment, default_jail_enable, ignore_ip, bantime, findtime, maxretry, destemail, banaction, banaction_allports, advanced_actions, geoip_provider, geoip_database_path, max_log_lines, console_output
|
||||
FROM app_settings
|
||||
WHERE id = 1`)
|
||||
|
||||
var (
|
||||
lang, callback, callbackSecret, alerts, smtpHost, smtpUser, smtpPass, smtpFrom, ignoreIP, bantime, findtime, destemail, banaction, banactionAllports, advancedActions, geoipProvider, geoipDatabasePath sql.NullString
|
||||
port, smtpPort, maxretry, maxLogLines sql.NullInt64
|
||||
debug, restartNeeded, smtpTLS, bantimeInc, defaultJailEn, emailAlertsForBans, emailAlertsForUnbans sql.NullInt64
|
||||
debug, restartNeeded, smtpTLS, bantimeInc, defaultJailEn, emailAlertsForBans, emailAlertsForUnbans, consoleOutput sql.NullInt64
|
||||
)
|
||||
|
||||
err := row.Scan(&lang, &port, &debug, &restartNeeded, &callback, &callbackSecret, &alerts, &emailAlertsForBans, &emailAlertsForUnbans, &smtpHost, &smtpPort, &smtpUser, &smtpPass, &smtpFrom, &smtpTLS, &bantimeInc, &defaultJailEn, &ignoreIP, &bantime, &findtime, &maxretry, &destemail, &banaction, &banactionAllports, &advancedActions, &geoipProvider, &geoipDatabasePath, &maxLogLines)
|
||||
err := row.Scan(&lang, &port, &debug, &restartNeeded, &callback, &callbackSecret, &alerts, &emailAlertsForBans, &emailAlertsForUnbans, &smtpHost, &smtpPort, &smtpUser, &smtpPass, &smtpFrom, &smtpTLS, &bantimeInc, &defaultJailEn, &ignoreIP, &bantime, &findtime, &maxretry, &destemail, &banaction, &banactionAllports, &advancedActions, &geoipProvider, &geoipDatabasePath, &maxLogLines, &consoleOutput)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return AppSettingsRecord{}, false, nil
|
||||
}
|
||||
@@ -243,6 +245,8 @@ WHERE id = 1`)
|
||||
GeoIPProvider: stringFromNull(geoipProvider),
|
||||
GeoIPDatabasePath: stringFromNull(geoipDatabasePath),
|
||||
MaxLogLines: intFromNull(maxLogLines),
|
||||
// Console output settings
|
||||
ConsoleOutput: intToBool(intFromNull(consoleOutput)),
|
||||
}
|
||||
|
||||
return rec, true, nil
|
||||
@@ -254,9 +258,9 @@ func SaveAppSettings(ctx context.Context, rec AppSettingsRecord) error {
|
||||
}
|
||||
_, err := db.ExecContext(ctx, `
|
||||
INSERT INTO app_settings (
|
||||
id, language, port, debug, restart_needed, callback_url, callback_secret, alert_countries, email_alerts_for_bans, email_alerts_for_unbans, smtp_host, smtp_port, smtp_username, smtp_password, smtp_from, smtp_use_tls, bantime_increment, default_jail_enable, ignore_ip, bantime, findtime, maxretry, destemail, banaction, banaction_allports, advanced_actions, geoip_provider, geoip_database_path, max_log_lines
|
||||
id, language, port, debug, restart_needed, callback_url, callback_secret, alert_countries, email_alerts_for_bans, email_alerts_for_unbans, smtp_host, smtp_port, smtp_username, smtp_password, smtp_from, smtp_use_tls, bantime_increment, default_jail_enable, ignore_ip, bantime, findtime, maxretry, destemail, banaction, banaction_allports, advanced_actions, geoip_provider, geoip_database_path, max_log_lines, console_output
|
||||
) VALUES (
|
||||
1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
|
||||
1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
|
||||
) ON CONFLICT(id) DO UPDATE SET
|
||||
language = excluded.language,
|
||||
port = excluded.port,
|
||||
@@ -285,7 +289,8 @@ INSERT INTO app_settings (
|
||||
advanced_actions = excluded.advanced_actions,
|
||||
geoip_provider = excluded.geoip_provider,
|
||||
geoip_database_path = excluded.geoip_database_path,
|
||||
max_log_lines = excluded.max_log_lines
|
||||
max_log_lines = excluded.max_log_lines,
|
||||
console_output = excluded.console_output
|
||||
`, rec.Language,
|
||||
rec.Port,
|
||||
boolToInt(rec.Debug),
|
||||
@@ -314,7 +319,7 @@ INSERT INTO app_settings (
|
||||
rec.GeoIPProvider,
|
||||
rec.GeoIPDatabasePath,
|
||||
rec.MaxLogLines,
|
||||
)
|
||||
boolToInt(rec.ConsoleOutput))
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -861,7 +866,9 @@ CREATE TABLE IF NOT EXISTS app_settings (
|
||||
advanced_actions TEXT,
|
||||
geoip_provider TEXT,
|
||||
geoip_database_path TEXT,
|
||||
max_log_lines INTEGER
|
||||
max_log_lines INTEGER,
|
||||
-- Console output settings
|
||||
console_output INTEGER DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS servers (
|
||||
@@ -933,6 +940,13 @@ CREATE INDEX IF NOT EXISTS idx_perm_blocks_status ON permanent_blocks(status);
|
||||
// return err
|
||||
// }
|
||||
// }
|
||||
|
||||
// Migration: Add console_output column if it doesn't exist
|
||||
if _, err := db.ExecContext(ctx, `ALTER TABLE app_settings ADD COLUMN console_output INTEGER DEFAULT 0`); err != nil {
|
||||
if err != nil && !strings.Contains(strings.ToLower(err.Error()), "duplicate column name") {
|
||||
return err
|
||||
}
|
||||
}
|
||||
_ = strings.Contains // Keep strings import for migration example above
|
||||
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user