Make default jail state configurable

This commit is contained in:
2025-12-15 18:57:50 +01:00
parent 55ccb5a32b
commit 5163e4f1f4
16 changed files with 71 additions and 23 deletions

View File

@@ -93,7 +93,6 @@ func main() {
}
}
// isLOTRModeActive checks if LOTR mode is enabled in alert countries
func isLOTRModeActive(alertCountries []string) bool {
if len(alertCountries) == 0 {
return false
@@ -106,7 +105,7 @@ func isLOTRModeActive(alertCountries []string) bool {
return false
}
// printWelcomeBanner prints a cool Tux banner with startup info.
// printWelcomeBanner prints the Tux banner with startup info.
func printWelcomeBanner(appPort string, isLOTRMode bool) {
greeting := getGreeting()

View File

@@ -29,7 +29,7 @@ services:
image: registry.swissmakers.ch/infra/fail2ban-ui:latest
#image: localhost/fail2ban-ui:dev
container_name: fail2ban-ui
#privileged: true
privileged: true # needed because the fail2ban-ui container needs to modify the fail2ban config owned by root inside the linuxserver-fail2ban container
network_mode: host
environment:
- PORT=3080

View File

@@ -61,6 +61,7 @@ type AppSettings struct {
// Fail2Ban [DEFAULT] section values from jail.local
BantimeIncrement bool `json:"bantimeIncrement"`
DefaultJailEnable bool `json:"defaultJailEnable"`
IgnoreIPs []string `json:"ignoreips"` // Changed from string to []string for individual IP management
Bantime string `json:"bantime"`
Findtime string `json:"findtime"`
@@ -351,6 +352,7 @@ func applyAppSettingsRecordLocked(rec storage.AppSettingsRecord) {
currentSettings.CallbackURL = rec.CallbackURL
currentSettings.RestartNeeded = rec.RestartNeeded
currentSettings.BantimeIncrement = rec.BantimeIncrement
currentSettings.DefaultJailEnable = rec.DefaultJailEnable
// Convert IgnoreIP string to array (backward compatibility)
if rec.IgnoreIP != "" {
currentSettings.IgnoreIPs = strings.Fields(rec.IgnoreIP)
@@ -446,6 +448,7 @@ func toAppSettingsRecordLocked() (storage.AppSettingsRecord, error) {
SMTPFrom: currentSettings.SMTP.From,
SMTPUseTLS: currentSettings.SMTP.UseTLS,
BantimeIncrement: currentSettings.BantimeIncrement,
DefaultJailEnable: currentSettings.DefaultJailEnable,
// Convert IgnoreIPs array to space-separated string for storage
IgnoreIP: strings.Join(currentSettings.IgnoreIPs, " "),
Bantime: currentSettings.Bantime,
@@ -808,6 +811,7 @@ func ensureJailLocalStructure() error {
banactionAllports = "iptables-allports"
}
defaultSection := fmt.Sprintf(`[DEFAULT]
enabled = %t
bantime.increment = %t
ignoreip = %s
bantime = %s
@@ -817,7 +821,7 @@ destemail = %s
banaction = %s
banaction_allports = %s
`, settings.BantimeIncrement, ignoreIPStr, settings.Bantime, settings.Findtime, settings.Maxretry, settings.Destemail, banaction, banactionAllports)
`, settings.DefaultJailEnable, settings.BantimeIncrement, ignoreIPStr, settings.Bantime, settings.Findtime, settings.Maxretry, settings.Destemail, banaction, banactionAllports)
// Build action_mwlg configuration
// Note: action_mwlg depends on action_ which depends on banaction (now defined above)
@@ -876,6 +880,7 @@ func updateJailLocalDefaultSection(settings AppSettings) error {
}
// Keys to update
keysToUpdate := map[string]string{
"enabled": fmt.Sprintf("enabled = %t", settings.DefaultJailEnable),
"bantime.increment": fmt.Sprintf("bantime.increment = %t", settings.BantimeIncrement),
"ignoreip": fmt.Sprintf("ignoreip = %s", ignoreIPStr),
"bantime": fmt.Sprintf("bantime = %s", settings.Bantime),
@@ -1347,6 +1352,7 @@ func UpdateSettings(new AppSettings) (AppSettings, error) {
}
}
restartTriggered := old.BantimeIncrement != new.BantimeIncrement ||
old.DefaultJailEnable != new.DefaultJailEnable ||
ignoreIPsChanged ||
old.Bantime != new.Bantime ||
old.Findtime != new.Findtime ||

View File

@@ -386,6 +386,7 @@ func (ac *AgentConnector) UpdateDefaultSettings(ctx context.Context, settings co
}
payload := map[string]interface{}{
"bantimeIncrement": settings.BantimeIncrement,
"defaultJailEnable": settings.DefaultJailEnable,
"ignoreip": ignoreIPStr,
"bantime": settings.Bantime,
"findtime": settings.Findtime,

View File

@@ -952,6 +952,7 @@ func (sc *SSHConnector) UpdateDefaultSettings(ctx context.Context, settings conf
}
// Define the keys we want to update
keysToUpdate := map[string]string{
"enabled": fmt.Sprintf("enabled = %t", settings.DefaultJailEnable),
"bantime.increment": fmt.Sprintf("bantime.increment = %t", settings.BantimeIncrement),
"ignoreip": fmt.Sprintf("ignoreip = %s", ignoreIPStr),
"bantime": fmt.Sprintf("bantime = %s", settings.Bantime),
@@ -966,7 +967,7 @@ func (sc *SSHConnector) UpdateDefaultSettings(ctx context.Context, settings conf
if existingContent == "" {
// File doesn't exist, create new one with DEFAULT section
defaultLines := []string{"[DEFAULT]"}
for _, key := range []string{"bantime.increment", "ignoreip", "bantime", "findtime", "maxretry", "destemail", "banaction", "banaction_allports"} {
for _, key := range []string{"enabled", "bantime.increment", "ignoreip", "bantime", "findtime", "maxretry", "destemail", "banaction", "banaction_allports"} {
defaultLines = append(defaultLines, keysToUpdate[key])
}
defaultLines = append(defaultLines, "")
@@ -991,14 +992,20 @@ jail_file = '%s'
ignore_ip_str = '%s'
banaction_val = '%s'
banaction_allports_val = '%s'
default_jail_enable_val = %t
bantime_increment_val = %t
bantime_val = '%s'
findtime_val = '%s'
maxretry_val = %d
destemail_val = '%s'
keys_to_update = {
'enabled': 'enabled = ' + str(default_jail_enable_val),
'bantime.increment': 'bantime.increment = ' + str(bantime_increment_val),
'ignoreip': 'ignoreip = ' + ignore_ip_str,
'bantime': 'bantime = %s',
'findtime': 'findtime = %s',
'maxretry': 'maxretry = %d',
'destemail': 'destemail = %s',
'bantime': 'bantime = ' + bantime_val,
'findtime': 'findtime = ' + findtime_val,
'maxretry': 'maxretry = ' + str(maxretry_val),
'destemail': 'destemail = ' + destemail_val,
'banaction': 'banaction = ' + banaction_val,
'banaction_allports': 'banaction_allports = ' + banaction_allports_val
}
@@ -1051,13 +1058,13 @@ for line in lines:
# If DEFAULT section wasn't found, create it at the beginning
if not default_section_found:
default_lines = ["[DEFAULT]\n"]
for key in ["bantime.increment", "ignoreip", "bantime", "findtime", "maxretry", "destemail"]:
for key in ["enabled", "bantime.increment", "ignoreip", "bantime", "findtime", "maxretry", "destemail"]:
default_lines.append(keys_to_update[key] + "\n")
default_lines.append("\n")
output_lines = default_lines + output_lines
else:
# Add any missing keys to the DEFAULT section
for key in ["bantime.increment", "ignoreip", "bantime", "findtime", "maxretry", "destemail"]:
for key in ["enabled", "bantime.increment", "ignoreip", "bantime", "findtime", "maxretry", "destemail"]:
if key not in keys_updated:
# Find the DEFAULT section and insert after it
for i, line in enumerate(output_lines):
@@ -1067,7 +1074,7 @@ else:
with open(jail_file, 'w') as f:
f.writelines(output_lines)
PY`, escapeForShell(jailLocalPath), escapeForShell(ignoreIPStr), escapeForShell(banactionVal), escapeForShell(banactionAllportsVal), settings.BantimeIncrement, escapeForShell(settings.Bantime), escapeForShell(settings.Findtime), settings.Maxretry, escapeForShell(settings.Destemail))
PY`, escapeForShell(jailLocalPath), escapeForShell(ignoreIPStr), escapeForShell(banactionVal), escapeForShell(banactionAllportsVal), settings.BantimeIncrement, settings.DefaultJailEnable, escapeForShell(settings.Bantime), escapeForShell(settings.Findtime), settings.Maxretry, escapeForShell(settings.Destemail))
_, err = sc.runRemoteCommand(ctx, []string{"bash", "-lc", updateScript})
return err
@@ -1109,6 +1116,7 @@ banaction_allports_val = '%s'
banner_content = """%s"""
settings = {
'bantime_increment': %t,
'default_jail_enable': %t,
'ignoreip': ignore_ip_str,
'bantime': '%s',
'findtime': '%s',
@@ -1169,6 +1177,7 @@ if has_full_banner and has_action_mwlg and has_action_override:
elif in_default:
key_updated = False
for key, new_value in [
('enabled', 'enabled = ' + str(settings['default_jail_enable'])),
('bantime.increment', 'bantime.increment = ' + str(settings['bantime_increment'])),
('ignoreip', 'ignoreip = ' + settings['ignoreip']),
('bantime', 'bantime = ' + settings['bantime']),
@@ -1192,6 +1201,7 @@ if has_full_banner and has_action_mwlg and has_action_override:
# Add missing keys
if in_default:
for key, new_value in [
('enabled', 'enabled = ' + str(settings['default_jail_enable'])),
('bantime.increment', 'bantime.increment = ' + str(settings['bantime_increment'])),
('ignoreip', 'ignoreip = ' + settings['ignoreip']),
('bantime', 'bantime = ' + settings['bantime']),
@@ -1214,6 +1224,7 @@ else:
banner = banner_content
default_section = """[DEFAULT]
enabled = """ + str(settings['default_jail_enable']) + """
bantime.increment = """ + str(settings['bantime_increment']) + """
ignoreip = """ + settings['ignoreip'] + """
bantime = """ + settings['bantime'] + """
@@ -1239,7 +1250,7 @@ action = %%(action_mwlg)s
with open(jail_file, 'w') as f:
f.write(new_content)
PY`, escapeForShell(jailLocalPath), escapeForShell(ignoreIPStr), escapeForShell(banactionVal), escapeForShell(banactionAllportsVal), escapeForShell(config.JailLocalBanner()), settings.BantimeIncrement,
PY`, escapeForShell(jailLocalPath), escapeForShell(ignoreIPStr), escapeForShell(banactionVal), escapeForShell(banactionAllportsVal), escapeForShell(config.JailLocalBanner()), settings.BantimeIncrement, settings.DefaultJailEnable,
escapeForShell(settings.Bantime), escapeForShell(settings.Findtime), settings.Maxretry, escapeForShell(settings.Destemail))
// IMPORTANT: Run migration FIRST before ensuring structure

View File

@@ -1023,6 +1023,7 @@ func UpdateDefaultSettingsLocal(settings config.AppSettings) error {
}
// Define the keys we want to update
keysToUpdate := map[string]string{
"enabled": fmt.Sprintf("enabled = %t", settings.DefaultJailEnable),
"bantime.increment": fmt.Sprintf("bantime.increment = %t", settings.BantimeIncrement),
"ignoreip": fmt.Sprintf("ignoreip = %s", ignoreIPStr),
"bantime": fmt.Sprintf("bantime = %s", settings.Bantime),
@@ -1042,7 +1043,7 @@ func UpdateDefaultSettingsLocal(settings config.AppSettings) error {
var newLines []string
newLines = append(newLines, strings.Split(strings.TrimRight(config.JailLocalBanner(), "\n"), "\n")...)
newLines = append(newLines, "[DEFAULT]")
for _, key := range []string{"bantime.increment", "ignoreip", "bantime", "findtime", "maxretry", "destemail", "banaction", "banaction_allports"} {
for _, key := range []string{"enabled", "bantime.increment", "ignoreip", "bantime", "findtime", "maxretry", "destemail", "banaction", "banaction_allports"} {
newLines = append(newLines, keysToUpdate[key])
}
newLines = append(newLines, "")
@@ -1115,14 +1116,14 @@ func UpdateDefaultSettingsLocal(settings config.AppSettings) error {
// If DEFAULT section wasn't found, create it at the beginning
if !defaultSectionFound {
defaultLines := []string{"[DEFAULT]"}
for _, key := range []string{"bantime.increment", "ignoreip", "bantime", "findtime", "maxretry", "destemail"} {
for _, key := range []string{"enabled", "bantime.increment", "ignoreip", "bantime", "findtime", "maxretry", "destemail"} {
defaultLines = append(defaultLines, keysToUpdate[key])
}
defaultLines = append(defaultLines, "")
outputLines = append(defaultLines, outputLines...)
} else {
// Add any missing keys to the DEFAULT section
for _, key := range []string{"bantime.increment", "ignoreip", "bantime", "findtime", "maxretry", "destemail", "banaction", "banaction_allports"} {
for _, key := range []string{"enabled", "bantime.increment", "ignoreip", "bantime", "findtime", "maxretry", "destemail", "banaction", "banaction_allports"} {
if !keysUpdated[key] {
// Find the DEFAULT section and insert after it
for i, line := range outputLines {

View File

@@ -123,6 +123,8 @@
"settings.fail2ban.description": "Diese Einstellungen werden auf allen aktivierten Fail2Ban-Servern angewendet und in deren jail.local [DEFAULT]-Abschnitt gespeichert.",
"settings.enable_bantime_increment": "Bantime-Inkrement aktivieren",
"settings.enable_bantime_increment.description": "Wenn auf true gesetzt, wird die Bantime nach der Formel: bantime = findtime * (Anzahl der Fehler / maxretry) * (1 + bantime.rndtime) berechnet.",
"settings.default_jail_enable": "Jails standardmässig aktivieren",
"settings.default_jail_enable.description": "Wenn aktiviert, werden alle Jails standardmässig aktiviert. Wenn deaktiviert, müssen Jails explizit aktiviert werden.",
"settings.default_bantime": "Standard-Bantime",
"settings.default_bantime.description": "Die Anzahl der Sekunden, für die ein Host gesperrt wird. Zeitformat: 1h = 1 Stunde, 1d = 1 Tag, 1w = 1 Woche, 1m = 1 Monat, 1y = 1 Jahr.",
"settings.default_bantime_placeholder": "z.B. 48h",

View File

@@ -123,6 +123,8 @@
"settings.fail2ban.description": "Die Einstellige werde uf alli aktivierte Fail2Ban-Server aagwändet und i däre jail.local [DEFAULT]-Abschnitt gspeicheret.",
"settings.enable_bantime_increment": "Bantime-Inkrement aktivierä",
"settings.enable_bantime_increment.description": "Wenn uf true gsetzt, wird d Bantime nach dr Formle: bantime = findtime * (Aazahl vo de Fähler / maxretry) * (1 + bantime.rndtime) berechnet.",
"settings.default_jail_enable": "Jails standardmässig aktivieren",
"settings.default_jail_enable.description": "Wenn aktiviert, werde alli Jails standardmässig aktiviert. Wenn deaktiviert, mues jedes Jails explizit aktiviert werde.",
"settings.default_bantime": "Standard-Bantime",
"settings.default_bantime.description": "D Aazahl vo de Sekunde, wo ä Host gsperrt wird. Zytformat: 1h = 1 Stund, 1d = 1 Tag, 1w = 1 Wuche, 1m = 1 Monet, 1y = 1 Jahr.",
"settings.default_bantime_placeholder": "z.B. 48h",

View File

@@ -123,6 +123,8 @@
"settings.fail2ban.description": "These settings will be applied to all enabled Fail2Ban servers and stored in their jail.local [DEFAULT] section.",
"settings.enable_bantime_increment": "Enable Bantime Increment",
"settings.enable_bantime_increment.description": "If set to true, the bantime will be calculated using the formula: bantime = findtime * (number of failures / maxretry) * (1 + bantime.rndtime).",
"settings.default_jail_enable": "Enable Jails by Default",
"settings.default_jail_enable.description": "If enabled, all jails will be enabled by default. When disabled, jails must be explicitly enabled.",
"settings.default_bantime": "Default Bantime",
"settings.default_bantime.description": "The number of seconds that a host is banned. Time format: 1h = 1 hour, 1d = 1 day, 1w = 1 week, 1m = 1 month, 1y = 1 year.",
"settings.default_bantime_placeholder": "e.g., 48h",

View File

@@ -123,6 +123,8 @@
"settings.fail2ban.description": "Estas configuraciones se aplicarán a todos los servidores Fail2Ban habilitados y se almacenarán en su sección [DEFAULT] de jail.local.",
"settings.enable_bantime_increment": "Habilitar incremento de Bantime",
"settings.enable_bantime_increment.description": "Si se establece en true, el bantime se calculará usando la fórmula: bantime = findtime * (número de fallos / maxretry) * (1 + bantime.rndtime).",
"settings.default_jail_enable": "Jails por defecto activados",
"settings.default_jail_enable.description": "Si está habilitado, todos los jails estarán habilitados por defecto. Cuando está deshabilitado, los jails deben habilitarse explícitamente.",
"settings.default_bantime": "Bantime por defecto",
"settings.default_bantime.description": "El número de segundos que un host está bloqueado. Formato de tiempo: 1h = 1 hora, 1d = 1 día, 1w = 1 semana, 1m = 1 mes, 1y = 1 año.",
"settings.default_bantime_placeholder": "p.ej., 48h",

View File

@@ -123,6 +123,8 @@
"settings.fail2ban.description": "Ces paramètres seront appliqués à tous les serveurs Fail2Ban activés et stockés dans leur section [DEFAULT] de jail.local.",
"settings.enable_bantime_increment": "Activer l'incrémentation du Bantime",
"settings.enable_bantime_increment.description": "Si défini sur true, le bantime sera calculé à l'aide de la formule : bantime = findtime * (nombre d'échecs / maxretry) * (1 + bantime.rndtime).",
"settings.default_jail_enable": "Jails par défaut activés",
"settings.default_jail_enable.description": "Si activé, tous les jails seront activés par défaut. Lorsqu'il est désactivé, les jails doivent être explicitement activés.",
"settings.default_bantime": "Bantime par défaut",
"settings.default_bantime.description": "Le nombre de secondes pendant lesquelles un hôte est banni. Format de temps : 1h = 1 heure, 1d = 1 jour, 1w = 1 semaine, 1m = 1 mois, 1y = 1 an.",
"settings.default_bantime_placeholder": "par exemple, 48h",

View File

@@ -123,6 +123,8 @@
"settings.fail2ban.description": "Queste impostazioni verranno applicate a tutti i server Fail2Ban abilitati e memorizzate nella loro sezione [DEFAULT] di jail.local.",
"settings.enable_bantime_increment": "Abilita incremento del Bantime",
"settings.enable_bantime_increment.description": "Se impostato su true, il bantime verrà calcolato utilizzando la formula: bantime = findtime * (numero di errori / maxretry) * (1 + bantime.rndtime).",
"settings.default_jail_enable": "Jails predefiniti attivati",
"settings.default_jail_enable.description": "Se abilitato, tutti i jails saranno abilitati per impostazione predefinita. Quando disabilitato, i jails devono essere esplicitamente abilitati.",
"settings.default_bantime": "Bantime predefinito",
"settings.default_bantime.description": "Il numero di secondi per cui un host viene bannato. Formato tempo: 1h = 1 ora, 1d = 1 giorno, 1w = 1 settimana, 1m = 1 mese, 1y = 1 anno.",
"settings.default_bantime_placeholder": "es. 48h",

View File

@@ -61,6 +61,7 @@ type AppSettingsRecord struct {
SMTPFrom string
SMTPUseTLS bool
BantimeIncrement bool
DefaultJailEnable bool
IgnoreIP string // Stored as space-separated string, converted to array in AppSettings
Bantime string
Findtime string
@@ -170,17 +171,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, 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
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 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, &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)
if errors.Is(err, sql.ErrNoRows) {
return AppSettingsRecord{}, false, nil
}
@@ -202,6 +203,7 @@ WHERE id = 1`)
SMTPFrom: stringFromNull(smtpFrom),
SMTPUseTLS: intToBool(intFromNull(smtpTLS)),
BantimeIncrement: intToBool(intFromNull(bantimeInc)),
DefaultJailEnable: intToBool(intFromNull(defaultJailEn)),
IgnoreIP: stringFromNull(ignoreIP),
Bantime: stringFromNull(bantime),
Findtime: stringFromNull(findtime),
@@ -221,9 +223,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, 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
) VALUES (
1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
) ON CONFLICT(id) DO UPDATE SET
language = excluded.language,
port = excluded.port,
@@ -238,6 +240,7 @@ INSERT INTO app_settings (
smtp_from = excluded.smtp_from,
smtp_use_tls = excluded.smtp_use_tls,
bantime_increment = excluded.bantime_increment,
default_jail_enable = excluded.default_jail_enable,
ignore_ip = excluded.ignore_ip,
bantime = excluded.bantime,
findtime = excluded.findtime,
@@ -259,6 +262,7 @@ INSERT INTO app_settings (
rec.SMTPFrom,
boolToInt(rec.SMTPUseTLS),
boolToInt(rec.BantimeIncrement),
boolToInt(rec.DefaultJailEnable),
rec.IgnoreIP,
rec.Bantime,
rec.Findtime,
@@ -775,6 +779,7 @@ CREATE TABLE IF NOT EXISTS app_settings (
smtp_from TEXT,
smtp_use_tls INTEGER,
bantime_increment INTEGER,
default_jail_enable INTEGER,
ignore_ip TEXT,
bantime TEXT,
findtime TEXT,

View File

@@ -1333,6 +1333,7 @@ func UpdateSettingsHandler(c *gin.Context) {
// Compare IgnoreIPs arrays
ignoreIPsChanged := !equalStringSlices(oldSettings.IgnoreIPs, newSettings.IgnoreIPs)
defaultSettingsChanged := oldSettings.BantimeIncrement != newSettings.BantimeIncrement ||
oldSettings.DefaultJailEnable != newSettings.DefaultJailEnable ||
ignoreIPsChanged ||
oldSettings.Bantime != newSettings.Bantime ||
oldSettings.Findtime != newSettings.Findtime ||
@@ -1459,6 +1460,7 @@ func ApplyFail2banSettings(jailLocalPath string) error {
newLines := []string{
"[DEFAULT]",
fmt.Sprintf("enabled = %t", s.DefaultJailEnable),
fmt.Sprintf("bantime.increment = %t", s.BantimeIncrement),
fmt.Sprintf("ignoreip = %s", strings.Join(s.IgnoreIPs, " ")),
fmt.Sprintf("bantime = %s", s.Bantime),

View File

@@ -82,6 +82,7 @@ function loadSettings() {
}
document.getElementById('bantimeIncrement').checked = data.bantimeIncrement || false;
document.getElementById('defaultJailEnable').checked = data.defaultJailEnable || false;
document.getElementById('banTime').value = data.bantime || '';
document.getElementById('findTime').value = data.findtime || '';
document.getElementById('maxRetry').value = data.maxretry || '';
@@ -141,6 +142,7 @@ function saveSettings(event) {
callbackUrl: callbackUrl,
alertCountries: selectedCountries.length > 0 ? selectedCountries : ["ALL"],
bantimeIncrement: document.getElementById('bantimeIncrement').checked,
defaultJailEnable: document.getElementById('defaultJailEnable').checked,
bantime: document.getElementById('banTime').value.trim(),
findtime: document.getElementById('findTime').value.trim(),
maxretry: parseInt(document.getElementById('maxRetry').value, 10) || 3,

View File

@@ -586,6 +586,15 @@
<p class="text-xs text-gray-500 ml-9" data-i18n="settings.enable_bantime_increment.description">If set to true, the bantime will be calculated using the formula: bantime = findtime * (number of failures / maxretry) * (1 + bantime.rndtime).</p>
</div>
<!-- Default Enabled -->
<div class="mb-4">
<div class="flex items-center mb-2">
<input type="checkbox" id="defaultJailEnable" class="h-4 w-7 text-blue-600 transition duration-150 ease-in-out" />
<label for="defaultJailEnable" class="ml-2 block text-sm font-medium text-gray-700" data-i18n="settings.default_jail_enable">Enable Jails by Default</label>
</div>
<p class="text-xs text-gray-500 ml-9" data-i18n="settings.default_jail_enable.description">If enabled, all jails will be enabled by default. When disabled, jails must be explicitly enabled.</p>
</div>
<!-- Bantime -->
<div class="mb-4">
<label for="banTime" class="block text-sm font-medium text-gray-700 mb-2" data-i18n="settings.default_bantime">Default Bantime</label>