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 { func isLOTRModeActive(alertCountries []string) bool {
if len(alertCountries) == 0 { if len(alertCountries) == 0 {
return false return false
@@ -106,10 +105,10 @@ func isLOTRModeActive(alertCountries []string) bool {
return false 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) { func printWelcomeBanner(appPort string, isLOTRMode bool) {
greeting := getGreeting() greeting := getGreeting()
if isLOTRMode { if isLOTRMode {
const lotrBanner = ` const lotrBanner = `
.--. .--.

View File

@@ -29,7 +29,7 @@ services:
image: registry.swissmakers.ch/infra/fail2ban-ui:latest image: registry.swissmakers.ch/infra/fail2ban-ui:latest
#image: localhost/fail2ban-ui:dev #image: localhost/fail2ban-ui:dev
container_name: fail2ban-ui 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 network_mode: host
environment: environment:
- PORT=3080 - PORT=3080

View File

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

View File

@@ -386,6 +386,7 @@ func (ac *AgentConnector) UpdateDefaultSettings(ctx context.Context, settings co
} }
payload := map[string]interface{}{ payload := map[string]interface{}{
"bantimeIncrement": settings.BantimeIncrement, "bantimeIncrement": settings.BantimeIncrement,
"defaultJailEnable": settings.DefaultJailEnable,
"ignoreip": ignoreIPStr, "ignoreip": ignoreIPStr,
"bantime": settings.Bantime, "bantime": settings.Bantime,
"findtime": settings.Findtime, "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 // Define the keys we want to update
keysToUpdate := map[string]string{ keysToUpdate := map[string]string{
"enabled": fmt.Sprintf("enabled = %t", settings.DefaultJailEnable),
"bantime.increment": fmt.Sprintf("bantime.increment = %t", settings.BantimeIncrement), "bantime.increment": fmt.Sprintf("bantime.increment = %t", settings.BantimeIncrement),
"ignoreip": fmt.Sprintf("ignoreip = %s", ignoreIPStr), "ignoreip": fmt.Sprintf("ignoreip = %s", ignoreIPStr),
"bantime": fmt.Sprintf("bantime = %s", settings.Bantime), "bantime": fmt.Sprintf("bantime = %s", settings.Bantime),
@@ -966,7 +967,7 @@ func (sc *SSHConnector) UpdateDefaultSettings(ctx context.Context, settings conf
if existingContent == "" { if existingContent == "" {
// File doesn't exist, create new one with DEFAULT section // File doesn't exist, create new one with DEFAULT section
defaultLines := []string{"[DEFAULT]"} 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, keysToUpdate[key])
} }
defaultLines = append(defaultLines, "") defaultLines = append(defaultLines, "")
@@ -991,14 +992,20 @@ jail_file = '%s'
ignore_ip_str = '%s' ignore_ip_str = '%s'
banaction_val = '%s' banaction_val = '%s'
banaction_allports_val = '%s' banaction_allports_val = '%s'
default_jail_enable_val = %t
bantime_increment_val = %t bantime_increment_val = %t
bantime_val = '%s'
findtime_val = '%s'
maxretry_val = %d
destemail_val = '%s'
keys_to_update = { keys_to_update = {
'enabled': 'enabled = ' + str(default_jail_enable_val),
'bantime.increment': 'bantime.increment = ' + str(bantime_increment_val), 'bantime.increment': 'bantime.increment = ' + str(bantime_increment_val),
'ignoreip': 'ignoreip = ' + ignore_ip_str, 'ignoreip': 'ignoreip = ' + ignore_ip_str,
'bantime': 'bantime = %s', 'bantime': 'bantime = ' + bantime_val,
'findtime': 'findtime = %s', 'findtime': 'findtime = ' + findtime_val,
'maxretry': 'maxretry = %d', 'maxretry': 'maxretry = ' + str(maxretry_val),
'destemail': 'destemail = %s', 'destemail': 'destemail = ' + destemail_val,
'banaction': 'banaction = ' + banaction_val, 'banaction': 'banaction = ' + banaction_val,
'banaction_allports': 'banaction_allports = ' + banaction_allports_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 DEFAULT section wasn't found, create it at the beginning
if not default_section_found: if not default_section_found:
default_lines = ["[DEFAULT]\n"] 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(keys_to_update[key] + "\n")
default_lines.append("\n") default_lines.append("\n")
output_lines = default_lines + output_lines output_lines = default_lines + output_lines
else: else:
# Add any missing keys to the DEFAULT section # 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: if key not in keys_updated:
# Find the DEFAULT section and insert after it # Find the DEFAULT section and insert after it
for i, line in enumerate(output_lines): for i, line in enumerate(output_lines):
@@ -1067,7 +1074,7 @@ else:
with open(jail_file, 'w') as f: with open(jail_file, 'w') as f:
f.writelines(output_lines) 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}) _, err = sc.runRemoteCommand(ctx, []string{"bash", "-lc", updateScript})
return err return err
@@ -1109,6 +1116,7 @@ banaction_allports_val = '%s'
banner_content = """%s""" banner_content = """%s"""
settings = { settings = {
'bantime_increment': %t, 'bantime_increment': %t,
'default_jail_enable': %t,
'ignoreip': ignore_ip_str, 'ignoreip': ignore_ip_str,
'bantime': '%s', 'bantime': '%s',
'findtime': '%s', 'findtime': '%s',
@@ -1169,6 +1177,7 @@ if has_full_banner and has_action_mwlg and has_action_override:
elif in_default: elif in_default:
key_updated = False key_updated = False
for key, new_value in [ for key, new_value in [
('enabled', 'enabled = ' + str(settings['default_jail_enable'])),
('bantime.increment', 'bantime.increment = ' + str(settings['bantime_increment'])), ('bantime.increment', 'bantime.increment = ' + str(settings['bantime_increment'])),
('ignoreip', 'ignoreip = ' + settings['ignoreip']), ('ignoreip', 'ignoreip = ' + settings['ignoreip']),
('bantime', 'bantime = ' + settings['bantime']), ('bantime', 'bantime = ' + settings['bantime']),
@@ -1192,6 +1201,7 @@ if has_full_banner and has_action_mwlg and has_action_override:
# Add missing keys # Add missing keys
if in_default: if in_default:
for key, new_value in [ for key, new_value in [
('enabled', 'enabled = ' + str(settings['default_jail_enable'])),
('bantime.increment', 'bantime.increment = ' + str(settings['bantime_increment'])), ('bantime.increment', 'bantime.increment = ' + str(settings['bantime_increment'])),
('ignoreip', 'ignoreip = ' + settings['ignoreip']), ('ignoreip', 'ignoreip = ' + settings['ignoreip']),
('bantime', 'bantime = ' + settings['bantime']), ('bantime', 'bantime = ' + settings['bantime']),
@@ -1214,6 +1224,7 @@ else:
banner = banner_content banner = banner_content
default_section = """[DEFAULT] default_section = """[DEFAULT]
enabled = """ + str(settings['default_jail_enable']) + """
bantime.increment = """ + str(settings['bantime_increment']) + """ bantime.increment = """ + str(settings['bantime_increment']) + """
ignoreip = """ + settings['ignoreip'] + """ ignoreip = """ + settings['ignoreip'] + """
bantime = """ + settings['bantime'] + """ bantime = """ + settings['bantime'] + """
@@ -1239,7 +1250,7 @@ action = %%(action_mwlg)s
with open(jail_file, 'w') as f: with open(jail_file, 'w') as f:
f.write(new_content) 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)) escapeForShell(settings.Bantime), escapeForShell(settings.Findtime), settings.Maxretry, escapeForShell(settings.Destemail))
// IMPORTANT: Run migration FIRST before ensuring structure // 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 // Define the keys we want to update
keysToUpdate := map[string]string{ keysToUpdate := map[string]string{
"enabled": fmt.Sprintf("enabled = %t", settings.DefaultJailEnable),
"bantime.increment": fmt.Sprintf("bantime.increment = %t", settings.BantimeIncrement), "bantime.increment": fmt.Sprintf("bantime.increment = %t", settings.BantimeIncrement),
"ignoreip": fmt.Sprintf("ignoreip = %s", ignoreIPStr), "ignoreip": fmt.Sprintf("ignoreip = %s", ignoreIPStr),
"bantime": fmt.Sprintf("bantime = %s", settings.Bantime), "bantime": fmt.Sprintf("bantime = %s", settings.Bantime),
@@ -1042,7 +1043,7 @@ func UpdateDefaultSettingsLocal(settings config.AppSettings) error {
var newLines []string var newLines []string
newLines = append(newLines, strings.Split(strings.TrimRight(config.JailLocalBanner(), "\n"), "\n")...) newLines = append(newLines, strings.Split(strings.TrimRight(config.JailLocalBanner(), "\n"), "\n")...)
newLines = append(newLines, "[DEFAULT]") 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, keysToUpdate[key])
} }
newLines = append(newLines, "") 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 DEFAULT section wasn't found, create it at the beginning
if !defaultSectionFound { if !defaultSectionFound {
defaultLines := []string{"[DEFAULT]"} 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, keysToUpdate[key])
} }
defaultLines = append(defaultLines, "") defaultLines = append(defaultLines, "")
outputLines = append(defaultLines, outputLines...) outputLines = append(defaultLines, outputLines...)
} else { } else {
// Add any missing keys to the DEFAULT section // 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] { if !keysUpdated[key] {
// Find the DEFAULT section and insert after it // Find the DEFAULT section and insert after it
for i, line := range outputLines { 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.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": "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.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": "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.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", "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.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": "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.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": "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.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", "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.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": "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.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": "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.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", "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.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": "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.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": "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.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", "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.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": "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.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": "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.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", "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.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": "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.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": "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.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", "settings.default_bantime_placeholder": "es. 48h",

View File

@@ -61,6 +61,7 @@ type AppSettingsRecord struct {
SMTPFrom string SMTPFrom string
SMTPUseTLS bool SMTPUseTLS bool
BantimeIncrement bool BantimeIncrement bool
DefaultJailEnable bool
IgnoreIP string // Stored as space-separated string, converted to array in AppSettings IgnoreIP string // Stored as space-separated string, converted to array in AppSettings
Bantime string Bantime string
Findtime string Findtime string
@@ -170,17 +171,17 @@ func GetAppSettings(ctx context.Context) (AppSettingsRecord, bool, error) {
} }
row := db.QueryRowContext(ctx, ` 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 FROM app_settings
WHERE id = 1`) WHERE id = 1`)
var ( var (
lang, callback, alerts, smtpHost, smtpUser, smtpPass, smtpFrom, ignoreIP, bantime, findtime, destemail, banaction, banactionAllports, advancedActions sql.NullString lang, callback, alerts, smtpHost, smtpUser, smtpPass, smtpFrom, ignoreIP, bantime, findtime, destemail, banaction, banactionAllports, advancedActions sql.NullString
port, smtpPort, maxretry sql.NullInt64 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) { if errors.Is(err, sql.ErrNoRows) {
return AppSettingsRecord{}, false, nil return AppSettingsRecord{}, false, nil
} }
@@ -202,6 +203,7 @@ WHERE id = 1`)
SMTPFrom: stringFromNull(smtpFrom), SMTPFrom: stringFromNull(smtpFrom),
SMTPUseTLS: intToBool(intFromNull(smtpTLS)), SMTPUseTLS: intToBool(intFromNull(smtpTLS)),
BantimeIncrement: intToBool(intFromNull(bantimeInc)), BantimeIncrement: intToBool(intFromNull(bantimeInc)),
DefaultJailEnable: intToBool(intFromNull(defaultJailEn)),
IgnoreIP: stringFromNull(ignoreIP), IgnoreIP: stringFromNull(ignoreIP),
Bantime: stringFromNull(bantime), Bantime: stringFromNull(bantime),
Findtime: stringFromNull(findtime), Findtime: stringFromNull(findtime),
@@ -221,9 +223,9 @@ func SaveAppSettings(ctx context.Context, rec AppSettingsRecord) error {
} }
_, err := db.ExecContext(ctx, ` _, err := db.ExecContext(ctx, `
INSERT INTO app_settings ( 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 ( ) VALUES (
1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
) ON CONFLICT(id) DO UPDATE SET ) ON CONFLICT(id) DO UPDATE SET
language = excluded.language, language = excluded.language,
port = excluded.port, port = excluded.port,
@@ -238,6 +240,7 @@ INSERT INTO app_settings (
smtp_from = excluded.smtp_from, smtp_from = excluded.smtp_from,
smtp_use_tls = excluded.smtp_use_tls, smtp_use_tls = excluded.smtp_use_tls,
bantime_increment = excluded.bantime_increment, bantime_increment = excluded.bantime_increment,
default_jail_enable = excluded.default_jail_enable,
ignore_ip = excluded.ignore_ip, ignore_ip = excluded.ignore_ip,
bantime = excluded.bantime, bantime = excluded.bantime,
findtime = excluded.findtime, findtime = excluded.findtime,
@@ -259,6 +262,7 @@ INSERT INTO app_settings (
rec.SMTPFrom, rec.SMTPFrom,
boolToInt(rec.SMTPUseTLS), boolToInt(rec.SMTPUseTLS),
boolToInt(rec.BantimeIncrement), boolToInt(rec.BantimeIncrement),
boolToInt(rec.DefaultJailEnable),
rec.IgnoreIP, rec.IgnoreIP,
rec.Bantime, rec.Bantime,
rec.Findtime, rec.Findtime,
@@ -775,6 +779,7 @@ CREATE TABLE IF NOT EXISTS app_settings (
smtp_from TEXT, smtp_from TEXT,
smtp_use_tls INTEGER, smtp_use_tls INTEGER,
bantime_increment INTEGER, bantime_increment INTEGER,
default_jail_enable INTEGER,
ignore_ip TEXT, ignore_ip TEXT,
bantime TEXT, bantime TEXT,
findtime TEXT, findtime TEXT,

View File

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

View File

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

View File

@@ -585,6 +585,15 @@
</div> </div>
<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> <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> </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 --> <!-- Bantime -->
<div class="mb-4"> <div class="mb-4">