mirror of
https://github.com/swissmakers/fail2ban-ui.git
synced 2026-04-17 05:53:15 +02:00
Implement geoIP and whois lookups directly from fail2ban-UI
This commit is contained in:
@@ -70,6 +70,11 @@ type AppSettings struct {
|
||||
Banaction string `json:"banaction"` // Default banning action
|
||||
BanactionAllports string `json:"banactionAllports"` // Allports banning action
|
||||
//Sender string `json:"sender"`
|
||||
|
||||
// GeoIP and Whois settings
|
||||
GeoIPProvider string `json:"geoipProvider"` // "maxmind" or "builtin"
|
||||
GeoIPDatabasePath string `json:"geoipDatabasePath"` // Path to MaxMind database (optional)
|
||||
MaxLogLines int `json:"maxLogLines"` // Maximum log lines to include (default: 50)
|
||||
}
|
||||
|
||||
type AdvancedActionsConfig struct {
|
||||
@@ -172,9 +177,8 @@ actionban = /usr/bin/curl -X POST __CALLBACK_URL__/api/ban \
|
||||
--arg jail '<name>' \
|
||||
--arg hostname '<fq-hostname>' \
|
||||
--arg failures '<failures>' \
|
||||
--arg whois "$(whois <ip> || echo 'missing whois program')" \
|
||||
--arg logs "$(tac <logpath> | grep <grepopts> -wF <ip>)" \
|
||||
'{serverId: $serverId, ip: $ip, jail: $jail, hostname: $hostname, failures: $failures, whois: $whois, logs: $logs}')"
|
||||
'{serverId: $serverId, ip: $ip, jail: $jail, hostname: $hostname, failures: $failures, logs: $logs}')"
|
||||
|
||||
[Init]
|
||||
|
||||
@@ -458,6 +462,9 @@ func toAppSettingsRecordLocked() (storage.AppSettingsRecord, error) {
|
||||
Banaction: currentSettings.Banaction,
|
||||
BanactionAllports: currentSettings.BanactionAllports,
|
||||
AdvancedActionsJSON: string(advancedBytes),
|
||||
GeoIPProvider: currentSettings.GeoIPProvider,
|
||||
GeoIPDatabasePath: currentSettings.GeoIPDatabasePath,
|
||||
MaxLogLines: currentSettings.MaxLogLines,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -577,6 +584,15 @@ func setDefaultsLocked() {
|
||||
if currentSettings.BanactionAllports == "" {
|
||||
currentSettings.BanactionAllports = "iptables-allports"
|
||||
}
|
||||
if currentSettings.GeoIPProvider == "" {
|
||||
currentSettings.GeoIPProvider = "builtin"
|
||||
}
|
||||
if currentSettings.GeoIPDatabasePath == "" {
|
||||
currentSettings.GeoIPDatabasePath = "/usr/share/GeoIP/GeoLite2-Country.mmdb"
|
||||
}
|
||||
if currentSettings.MaxLogLines == 0 {
|
||||
currentSettings.MaxLogLines = 50
|
||||
}
|
||||
|
||||
if (currentSettings.AdvancedActions == AdvancedActionsConfig{}) {
|
||||
currentSettings.AdvancedActions = defaultAdvancedActionsConfig()
|
||||
|
||||
@@ -138,6 +138,14 @@
|
||||
"settings.default_max_retry": "Standard-Maximalversuche",
|
||||
"settings.default_max_retry.description": "Anzahl der Fehler, bevor ein Host gesperrt wird.",
|
||||
"settings.default_max_retry_placeholder": "Geben Sie die maximale Anzahl der Versuche ein",
|
||||
"settings.geoip_provider": "GeoIP-Anbieter",
|
||||
"settings.geoip_provider.description": "Wählen Sie den GeoIP-Lookup-Anbieter. MaxMind erfordert eine lokale Datenbankdatei, während Built-in eine kostenlose Online-API verwendet.",
|
||||
"settings.geoip_provider.maxmind": "MaxMind (Lokale Datenbank)",
|
||||
"settings.geoip_provider.builtin": "Built-in (ip-api.com)",
|
||||
"settings.geoip_database_path": "GeoIP-Datenbankpfad",
|
||||
"settings.geoip_database_path.description": "Pfad zur MaxMind GeoLite2-Country-Datenbankdatei.",
|
||||
"settings.max_log_lines": "Maximale Log-Zeilen",
|
||||
"settings.max_log_lines.description": "Maximale Anzahl von Log-Zeilen, die in Ban-Benachrichtigungen enthalten sein sollen. Die relevantesten Zeilen werden automatisch ausgewählt.",
|
||||
"settings.ignore_ips": "IP-Adressen ignorieren",
|
||||
"settings.ignore_ips.description": "Durch Leerzeichen getrennte Liste von IP-Adressen, CIDR-Masken oder DNS-Hosts. Fail2ban wird keinen Host sperren, der mit einer Adresse in dieser Liste übereinstimmt.",
|
||||
"settings.ignore_ips_placeholder": "IP-Adressen, getrennt durch Leerzeichen",
|
||||
|
||||
@@ -138,6 +138,14 @@
|
||||
"settings.default_max_retry": "Standard-Maximalversüech",
|
||||
"settings.default_max_retry.description": "Aazahl vo de Fähler, bevor ä Host gsperrt wird.",
|
||||
"settings.default_max_retry_placeholder": "Gib d'maximal Versüech ii",
|
||||
"settings.geoip_provider": "GeoIP-Aabieter",
|
||||
"settings.geoip_provider.description": "Wähl di GeoIP-Aabieter. MaxMind brucht e lokali Datenbankdatei, während Built-in e gratis Online-API verwendet.",
|
||||
"settings.geoip_provider.maxmind": "MaxMind (Lokali Datenbank)",
|
||||
"settings.geoip_provider.builtin": "Built-in (ip-api.com)",
|
||||
"settings.geoip_database_path": "GeoIP-Datenbankpfad",
|
||||
"settings.geoip_database_path.description": "Pfad zur MaxMind GeoLite2-Country-Datebank.",
|
||||
"settings.max_log_lines": "Maximali Log-Zeile",
|
||||
"settings.max_log_lines.description": "Maximali Aazahl vo Log-Zeile, wo i Ban-Benachrichtigunge enthalte si söll. Di relevanteschte Zeile werdet automatisch usgwählt.",
|
||||
"settings.ignore_ips": "IPs ignorierä",
|
||||
"settings.ignore_ips.description": "Dur Leerzeichä trennti Lischte vo IP-Adrässe, CIDR-Maske oder DNS-Hosts. Fail2ban wird kei Host sperre, wo mit ere Adrässe i dere Lischte übereistimmt.",
|
||||
"settings.ignore_ips_placeholder": "IPs, getrennt dur e Leerzeichä",
|
||||
|
||||
@@ -138,6 +138,14 @@
|
||||
"settings.default_max_retry": "Default Max Retry",
|
||||
"settings.default_max_retry.description": "Number of failures before a host gets banned.",
|
||||
"settings.default_max_retry_placeholder": "Enter maximum retries",
|
||||
"settings.geoip_provider": "GeoIP Provider",
|
||||
"settings.geoip_provider.description": "Choose the GeoIP lookup provider. MaxMind requires a local database file, while Built-in uses a free online API.",
|
||||
"settings.geoip_provider.maxmind": "MaxMind (Local Database)",
|
||||
"settings.geoip_provider.builtin": "Built-in (ip-api.com)",
|
||||
"settings.geoip_database_path": "GeoIP Database Path",
|
||||
"settings.geoip_database_path.description": "Path to the MaxMind GeoLite2-Country database file.",
|
||||
"settings.max_log_lines": "Maximum Log Lines",
|
||||
"settings.max_log_lines.description": "Maximum number of log lines to include in ban notifications. Most relevant lines are selected automatically.",
|
||||
"settings.ignore_ips": "Ignore IPs",
|
||||
"settings.ignore_ips.description": "Space separated list of IP addresses, CIDR masks or DNS hosts. Fail2ban will not ban a host which matches an address in this list.",
|
||||
"settings.ignore_ips_placeholder": "IPs to ignore, separated by spaces",
|
||||
|
||||
@@ -138,6 +138,14 @@
|
||||
"settings.default_max_retry": "Número máximo de reintentos por defecto",
|
||||
"settings.default_max_retry.description": "Número de fallos antes de que un host sea bloqueado.",
|
||||
"settings.default_max_retry_placeholder": "Introduce el número máximo de reintentos",
|
||||
"settings.geoip_provider": "Proveedor de GeoIP",
|
||||
"settings.geoip_provider.description": "Elija el proveedor de consulta GeoIP. MaxMind requiere un archivo de base de datos local, mientras que Built-in utiliza una API en línea gratuita.",
|
||||
"settings.geoip_provider.maxmind": "MaxMind (Base de Datos Local)",
|
||||
"settings.geoip_provider.builtin": "Built-in (ip-api.com)",
|
||||
"settings.geoip_database_path": "Ruta de la Base de Datos GeoIP",
|
||||
"settings.geoip_database_path.description": "Ruta al archivo de base de datos MaxMind GeoLite2-Country.",
|
||||
"settings.max_log_lines": "Líneas de Log Máximas",
|
||||
"settings.max_log_lines.description": "Número máximo de líneas de log a incluir en las notificaciones de bloqueo. Las líneas más relevantes se seleccionan automáticamente.",
|
||||
"settings.ignore_ips": "Ignorar IPs",
|
||||
"settings.ignore_ips.description": "Lista separada por espacios de direcciones IP, máscaras CIDR o hosts DNS. Fail2ban no bloqueará un host que coincida con una dirección en esta lista.",
|
||||
"settings.ignore_ips_placeholder": "IPs a ignorar, separadas por espacios",
|
||||
|
||||
@@ -138,6 +138,14 @@
|
||||
"settings.default_max_retry": "Nombre maximal de réessais par défaut",
|
||||
"settings.default_max_retry.description": "Nombre d'échecs avant qu'un hôte ne soit banni.",
|
||||
"settings.default_max_retry_placeholder": "Entrez le nombre maximal de réessais",
|
||||
"settings.geoip_provider": "Fournisseur GeoIP",
|
||||
"settings.geoip_provider.description": "Choisissez le fournisseur de recherche GeoIP. MaxMind nécessite un fichier de base de données local, tandis que Built-in utilise une API en ligne gratuite.",
|
||||
"settings.geoip_provider.maxmind": "MaxMind (Base de Données Locale)",
|
||||
"settings.geoip_provider.builtin": "Built-in (ip-api.com)",
|
||||
"settings.geoip_database_path": "Chemin de la Base de Données GeoIP",
|
||||
"settings.geoip_database_path.description": "Chemin vers le fichier de base de données MaxMind GeoLite2-Country.",
|
||||
"settings.max_log_lines": "Lignes de Log Maximales",
|
||||
"settings.max_log_lines.description": "Nombre maximal de lignes de log à inclure dans les notifications de bannissement. Les lignes les plus pertinentes sont sélectionnées automatiquement.",
|
||||
"settings.ignore_ips": "Ignorer les IPs",
|
||||
"settings.ignore_ips.description": "Liste séparée par des espaces d'adresses IP, de masques CIDR ou d'hôtes DNS. Fail2ban ne bannira pas un hôte qui correspond à une adresse de cette liste.",
|
||||
"settings.ignore_ips_placeholder": "IPs à ignorer, séparées par des espaces",
|
||||
|
||||
@@ -138,6 +138,14 @@
|
||||
"settings.default_max_retry": "Numero massimo di tentativi predefinito",
|
||||
"settings.default_max_retry.description": "Numero di errori prima che un host venga bannato.",
|
||||
"settings.default_max_retry_placeholder": "Inserisci il numero massimo di tentativi",
|
||||
"settings.geoip_provider": "Provider GeoIP",
|
||||
"settings.geoip_provider.description": "Scegli il provider di ricerca GeoIP. MaxMind richiede un file di database locale, mentre Built-in utilizza un'API online gratuita.",
|
||||
"settings.geoip_provider.maxmind": "MaxMind (Database Locale)",
|
||||
"settings.geoip_provider.builtin": "Built-in (ip-api.com)",
|
||||
"settings.geoip_database_path": "Percorso Database GeoIP",
|
||||
"settings.geoip_database_path.description": "Percorso al file del database MaxMind GeoLite2-Country.",
|
||||
"settings.max_log_lines": "Righe di Log Massime",
|
||||
"settings.max_log_lines.description": "Numero massimo di righe di log da includere nelle notifiche di ban. Le righe più rilevanti vengono selezionate automaticamente.",
|
||||
"settings.ignore_ips": "Ignora IP",
|
||||
"settings.ignore_ips.description": "Elenco separato da spazi di indirizzi IP, maschere CIDR o host DNS. Fail2ban non bannerà un host che corrisponde a un indirizzo in questo elenco.",
|
||||
"settings.ignore_ips_placeholder": "IP da ignorare, separate da spazi",
|
||||
|
||||
@@ -70,6 +70,9 @@ type AppSettingsRecord struct {
|
||||
Banaction string
|
||||
BanactionAllports string
|
||||
AdvancedActionsJSON string
|
||||
GeoIPProvider string
|
||||
GeoIPDatabasePath string
|
||||
MaxLogLines int
|
||||
}
|
||||
|
||||
type ServerRecord struct {
|
||||
@@ -171,17 +174,17 @@ func GetAppSettings(ctx context.Context) (AppSettingsRecord, bool, error) {
|
||||
}
|
||||
|
||||
row := db.QueryRowContext(ctx, `
|
||||
SELECT language, port, debug, callback_url, restart_needed, alert_countries, 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
|
||||
SELECT language, port, debug, callback_url, restart_needed, alert_countries, 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
|
||||
FROM app_settings
|
||||
WHERE id = 1`)
|
||||
|
||||
var (
|
||||
lang, callback, alerts, smtpHost, smtpUser, smtpPass, smtpFrom, ignoreIP, bantime, findtime, destemail, banaction, banactionAllports, advancedActions sql.NullString
|
||||
port, smtpPort, maxretry sql.NullInt64
|
||||
debug, restartNeeded, smtpTLS, bantimeInc, defaultJailEn sql.NullInt64
|
||||
lang, callback, 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 sql.NullInt64
|
||||
)
|
||||
|
||||
err := row.Scan(&lang, &port, &debug, &callback, &restartNeeded, &alerts, &smtpHost, &smtpPort, &smtpUser, &smtpPass, &smtpFrom, &smtpTLS, &bantimeInc, &defaultJailEn, &ignoreIP, &bantime, &findtime, &maxretry, &destemail, &banaction, &banactionAllports, &advancedActions)
|
||||
err := row.Scan(&lang, &port, &debug, &callback, &restartNeeded, &alerts, &smtpHost, &smtpPort, &smtpUser, &smtpPass, &smtpFrom, &smtpTLS, &bantimeInc, &defaultJailEn, &ignoreIP, &bantime, &findtime, &maxretry, &destemail, &banaction, &banactionAllports, &advancedActions, &geoipProvider, &geoipDatabasePath, &maxLogLines)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return AppSettingsRecord{}, false, nil
|
||||
}
|
||||
@@ -212,6 +215,9 @@ WHERE id = 1`)
|
||||
Banaction: stringFromNull(banaction),
|
||||
BanactionAllports: stringFromNull(banactionAllports),
|
||||
AdvancedActionsJSON: stringFromNull(advancedActions),
|
||||
GeoIPProvider: stringFromNull(geoipProvider),
|
||||
GeoIPDatabasePath: stringFromNull(geoipDatabasePath),
|
||||
MaxLogLines: intFromNull(maxLogLines),
|
||||
}
|
||||
|
||||
return rec, true, nil
|
||||
@@ -223,9 +229,9 @@ func SaveAppSettings(ctx context.Context, rec AppSettingsRecord) error {
|
||||
}
|
||||
_, err := db.ExecContext(ctx, `
|
||||
INSERT INTO app_settings (
|
||||
id, language, port, debug, callback_url, restart_needed, alert_countries, 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
|
||||
id, language, port, debug, callback_url, restart_needed, alert_countries, 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
|
||||
) VALUES (
|
||||
1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
|
||||
1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
|
||||
) ON CONFLICT(id) DO UPDATE SET
|
||||
language = excluded.language,
|
||||
port = excluded.port,
|
||||
@@ -248,7 +254,10 @@ INSERT INTO app_settings (
|
||||
destemail = excluded.destemail,
|
||||
banaction = excluded.banaction,
|
||||
banaction_allports = excluded.banaction_allports,
|
||||
advanced_actions = excluded.advanced_actions
|
||||
advanced_actions = excluded.advanced_actions,
|
||||
geoip_provider = excluded.geoip_provider,
|
||||
geoip_database_path = excluded.geoip_database_path,
|
||||
max_log_lines = excluded.max_log_lines
|
||||
`, rec.Language,
|
||||
rec.Port,
|
||||
boolToInt(rec.Debug),
|
||||
@@ -271,6 +280,9 @@ INSERT INTO app_settings (
|
||||
rec.Banaction,
|
||||
rec.BanactionAllports,
|
||||
rec.AdvancedActionsJSON,
|
||||
rec.GeoIPProvider,
|
||||
rec.GeoIPDatabasePath,
|
||||
rec.MaxLogLines,
|
||||
)
|
||||
return err
|
||||
}
|
||||
@@ -451,7 +463,7 @@ INSERT INTO ban_events (
|
||||
server_id, server_name, jail, ip, country, hostname, failures, whois, logs, occurred_at, created_at
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
||||
|
||||
result, err := db.ExecContext(
|
||||
_, err := db.ExecContext(
|
||||
ctx,
|
||||
query,
|
||||
record.ServerID,
|
||||
@@ -470,12 +482,6 @@ INSERT INTO ban_events (
|
||||
return err
|
||||
}
|
||||
|
||||
// Get the inserted ID
|
||||
id, err := result.LastInsertId()
|
||||
if err == nil {
|
||||
record.ID = id
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -797,7 +803,10 @@ CREATE TABLE IF NOT EXISTS app_settings (
|
||||
destemail TEXT,
|
||||
banaction TEXT,
|
||||
banaction_allports TEXT,
|
||||
advanced_actions TEXT
|
||||
advanced_actions TEXT,
|
||||
geoip_provider TEXT,
|
||||
geoip_database_path TEXT,
|
||||
max_log_lines INTEGER
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS servers (
|
||||
@@ -884,6 +893,38 @@ CREATE INDEX IF NOT EXISTS idx_perm_blocks_status ON permanent_blocks(status);
|
||||
}
|
||||
}
|
||||
|
||||
// Add geoip_provider column
|
||||
if _, err := db.ExecContext(ctx, `ALTER TABLE app_settings ADD COLUMN geoip_provider TEXT`); err != nil {
|
||||
if !strings.Contains(strings.ToLower(err.Error()), "duplicate column name") {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Add geoip_database_path column
|
||||
if _, err := db.ExecContext(ctx, `ALTER TABLE app_settings ADD COLUMN geoip_database_path TEXT`); err != nil {
|
||||
if !strings.Contains(strings.ToLower(err.Error()), "duplicate column name") {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Add max_log_lines column
|
||||
if _, err := db.ExecContext(ctx, `ALTER TABLE app_settings ADD COLUMN max_log_lines INTEGER`); err != nil {
|
||||
if !strings.Contains(strings.ToLower(err.Error()), "duplicate column name") {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Set default values for new columns if they are NULL
|
||||
if _, err := db.ExecContext(ctx, `UPDATE app_settings SET geoip_provider = 'maxmind' WHERE geoip_provider IS NULL`); err != nil {
|
||||
log.Printf("Warning: Failed to set default value for geoip_provider: %v", err)
|
||||
}
|
||||
if _, err := db.ExecContext(ctx, `UPDATE app_settings SET geoip_database_path = '/usr/share/GeoIP/GeoLite2-Country.mmdb' WHERE geoip_database_path IS NULL`); err != nil {
|
||||
log.Printf("Warning: Failed to set default value for geoip_database_path: %v", err)
|
||||
}
|
||||
if _, err := db.ExecContext(ctx, `UPDATE app_settings SET max_log_lines = 50 WHERE max_log_lines IS NULL OR max_log_lines = 0`); err != nil {
|
||||
log.Printf("Warning: Failed to set default value for max_log_lines: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user