mirror of
https://github.com/swissmakers/fail2ban-ui.git
synced 2026-04-17 14:03:15 +02:00
Add default chain and default BantimeRndtime settings and make configurable through the settings page
This commit is contained in:
@@ -424,6 +424,10 @@ func (ac *AgentConnector) UpdateDefaultSettings(ctx context.Context, settings co
|
||||
if banactionAllports == "" {
|
||||
banactionAllports = "nftables-allports"
|
||||
}
|
||||
chain := settings.Chain
|
||||
if chain == "" {
|
||||
chain = "INPUT"
|
||||
}
|
||||
payload := map[string]interface{}{
|
||||
"bantimeIncrement": settings.BantimeIncrement,
|
||||
"defaultJailEnable": settings.DefaultJailEnable,
|
||||
@@ -433,6 +437,8 @@ func (ac *AgentConnector) UpdateDefaultSettings(ctx context.Context, settings co
|
||||
"maxretry": settings.Maxretry,
|
||||
"banaction": banaction,
|
||||
"banactionAllports": banactionAllports,
|
||||
"chain": chain,
|
||||
"bantimeRndtime": settings.BantimeRndtime,
|
||||
}
|
||||
return ac.put(ctx, "/v1/jails/default-settings", payload, nil)
|
||||
}
|
||||
|
||||
@@ -1618,6 +1618,10 @@ func (sc *SSHConnector) UpdateDefaultSettings(ctx context.Context, settings conf
|
||||
if banactionAllportsVal == "" {
|
||||
banactionAllportsVal = "nftables-allports"
|
||||
}
|
||||
chainVal := settings.Chain
|
||||
if chainVal == "" {
|
||||
chainVal = "INPUT"
|
||||
}
|
||||
// Define the keys we want to update
|
||||
keysToUpdate := map[string]string{
|
||||
"enabled": fmt.Sprintf("enabled = %t", settings.DefaultJailEnable),
|
||||
@@ -1628,13 +1632,21 @@ func (sc *SSHConnector) UpdateDefaultSettings(ctx context.Context, settings conf
|
||||
"maxretry": fmt.Sprintf("maxretry = %d", settings.Maxretry),
|
||||
"banaction": fmt.Sprintf("banaction = %s", banactionVal),
|
||||
"banaction_allports": fmt.Sprintf("banaction_allports = %s", banactionAllportsVal),
|
||||
"chain": fmt.Sprintf("chain = %s", chainVal),
|
||||
}
|
||||
if settings.BantimeRndtime != "" {
|
||||
keysToUpdate["bantime.rndtime"] = fmt.Sprintf("bantime.rndtime = %s", settings.BantimeRndtime)
|
||||
}
|
||||
defaultKeysOrder := []string{"enabled", "bantime.increment", "ignoreip", "bantime", "findtime", "maxretry", "banaction", "banaction_allports", "chain"}
|
||||
if settings.BantimeRndtime != "" {
|
||||
defaultKeysOrder = append(defaultKeysOrder, "bantime.rndtime")
|
||||
}
|
||||
|
||||
// Parse existing content and update only specific keys in DEFAULT section
|
||||
if existingContent == "" {
|
||||
// File doesn't exist, create new one with DEFAULT section
|
||||
defaultLines := []string{"[DEFAULT]"}
|
||||
for _, key := range []string{"enabled", "bantime.increment", "ignoreip", "bantime", "findtime", "maxretry", "banaction", "banaction_allports"} {
|
||||
for _, key := range defaultKeysOrder {
|
||||
defaultLines = append(defaultLines, keysToUpdate[key])
|
||||
}
|
||||
defaultLines = append(defaultLines, "")
|
||||
@@ -1662,6 +1674,11 @@ func (sc *SSHConnector) UpdateDefaultSettings(ctx context.Context, settings conf
|
||||
bantimeIncrementPython = "True"
|
||||
}
|
||||
|
||||
chainValEsc := escapeForShell(chainVal)
|
||||
bantimeRndtimeEsc := ""
|
||||
if settings.BantimeRndtime != "" {
|
||||
bantimeRndtimeEsc = escapeForShell(settings.BantimeRndtime)
|
||||
}
|
||||
updateScript := fmt.Sprintf(`python3 <<'PY'
|
||||
import re
|
||||
|
||||
@@ -1674,6 +1691,8 @@ bantime_increment_val = %s
|
||||
bantime_val = '%s'
|
||||
findtime_val = '%s'
|
||||
maxretry_val = %d
|
||||
chain_val = '%s'
|
||||
bantime_rndtime_val = '%s'
|
||||
keys_to_update = {
|
||||
'enabled': 'enabled = ' + str(default_jail_enable_val).lower(),
|
||||
'bantime.increment': 'bantime.increment = ' + str(bantime_increment_val).lower(),
|
||||
@@ -1682,8 +1701,14 @@ keys_to_update = {
|
||||
'findtime': 'findtime = ' + findtime_val,
|
||||
'maxretry': 'maxretry = ' + str(maxretry_val),
|
||||
'banaction': 'banaction = ' + banaction_val,
|
||||
'banaction_allports': 'banaction_allports = ' + banaction_allports_val
|
||||
'banaction_allports': 'banaction_allports = ' + banaction_allports_val,
|
||||
'chain': 'chain = ' + chain_val
|
||||
}
|
||||
if bantime_rndtime_val:
|
||||
keys_to_update['bantime.rndtime'] = 'bantime.rndtime = ' + bantime_rndtime_val
|
||||
keys_order = ['enabled', 'bantime.increment', 'ignoreip', 'bantime', 'findtime', 'maxretry', 'banaction', 'banaction_allports', 'chain']
|
||||
if bantime_rndtime_val:
|
||||
keys_order.append('bantime.rndtime')
|
||||
|
||||
try:
|
||||
with open(jail_file, 'r') as f:
|
||||
@@ -1716,13 +1741,18 @@ for line in lines:
|
||||
elif in_default:
|
||||
# Check if this line is a key we need to update
|
||||
key_updated = False
|
||||
for key, new_value in keys_to_update.items():
|
||||
pattern = r'^\s*' + re.escape(key) + r'\s*='
|
||||
if re.match(pattern, stripped):
|
||||
output_lines.append(new_value + '\n')
|
||||
keys_updated.add(key)
|
||||
key_updated = True
|
||||
break
|
||||
# When user cleared bantime.rndtime, remove the line from config instead of keeping old value
|
||||
if not bantime_rndtime_val and re.match(r'^\s*bantime\.rndtime\s*=', stripped):
|
||||
key_updated = True
|
||||
# don't append: line is removed
|
||||
if not key_updated:
|
||||
for key, new_value in keys_to_update.items():
|
||||
pattern = r'^\s*' + re.escape(key) + r'\s*='
|
||||
if re.match(pattern, stripped):
|
||||
output_lines.append(new_value + '\n')
|
||||
keys_updated.add(key)
|
||||
key_updated = True
|
||||
break
|
||||
if not key_updated:
|
||||
# Keep the line as-is (might be action_mwlg or other DEFAULT settings)
|
||||
output_lines.append(line)
|
||||
@@ -1733,13 +1763,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 ["enabled", "bantime.increment", "ignoreip", "bantime", "findtime", "maxretry", "banaction", "banaction_allports"]:
|
||||
for key in keys_order:
|
||||
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 ["enabled", "bantime.increment", "ignoreip", "bantime", "findtime", "maxretry", "banaction", "banaction_allports"]:
|
||||
for key in keys_order:
|
||||
if key not in keys_updated:
|
||||
# Find the DEFAULT section and insert after it
|
||||
for i, line in enumerate(output_lines):
|
||||
@@ -1749,7 +1779,7 @@ else:
|
||||
|
||||
with open(jail_file, 'w') as f:
|
||||
f.writelines(output_lines)
|
||||
PY`, escapeForShell(jailLocalPath), escapeForShell(ignoreIPStr), escapeForShell(banactionVal), escapeForShell(banactionAllportsVal), defaultJailEnablePython, bantimeIncrementPython, escapeForShell(settings.Bantime), escapeForShell(settings.Findtime), settings.Maxretry)
|
||||
PY`, escapeForShell(jailLocalPath), escapeForShell(ignoreIPStr), escapeForShell(banactionVal), escapeForShell(banactionAllportsVal), defaultJailEnablePython, bantimeIncrementPython, escapeForShell(settings.Bantime), escapeForShell(settings.Findtime), settings.Maxretry, chainValEsc, bantimeRndtimeEsc)
|
||||
|
||||
_, err = sc.runRemoteCommand(ctx, []string{updateScript})
|
||||
return err
|
||||
@@ -1779,6 +1809,10 @@ func (sc *SSHConnector) EnsureJailLocalStructure(ctx context.Context) error {
|
||||
if banactionAllportsVal == "" {
|
||||
banactionAllportsVal = "nftables-allports"
|
||||
}
|
||||
chainVal := settings.Chain
|
||||
if chainVal == "" {
|
||||
chainVal = "INPUT"
|
||||
}
|
||||
|
||||
// Build the new jail.local content in Go (mirrors local ensureJailLocalStructure)
|
||||
banner := config.JailLocalBanner()
|
||||
@@ -1792,6 +1826,7 @@ findtime = %s
|
||||
maxretry = %d
|
||||
banaction = %s
|
||||
banaction_allports = %s
|
||||
chain = %s
|
||||
|
||||
`,
|
||||
settings.DefaultJailEnable,
|
||||
@@ -1802,7 +1837,12 @@ banaction_allports = %s
|
||||
settings.Maxretry,
|
||||
banactionVal,
|
||||
banactionAllportsVal,
|
||||
chainVal,
|
||||
)
|
||||
if settings.BantimeRndtime != "" {
|
||||
defaultSection += fmt.Sprintf("bantime.rndtime = %s\n", settings.BantimeRndtime)
|
||||
}
|
||||
defaultSection += "\n"
|
||||
|
||||
actionMwlgConfig := `# Custom Fail2Ban action for UI callbacks
|
||||
action_mwlg = %(action_)s
|
||||
|
||||
@@ -1236,6 +1236,10 @@ func UpdateDefaultSettingsLocal(settings config.AppSettings) error {
|
||||
if banactionAllports == "" {
|
||||
banactionAllports = "nftables-allports"
|
||||
}
|
||||
chain := settings.Chain
|
||||
if chain == "" {
|
||||
chain = "INPUT"
|
||||
}
|
||||
// Define the keys we want to update
|
||||
keysToUpdate := map[string]string{
|
||||
"enabled": fmt.Sprintf("enabled = %t", settings.DefaultJailEnable),
|
||||
@@ -1246,6 +1250,14 @@ func UpdateDefaultSettingsLocal(settings config.AppSettings) error {
|
||||
"maxretry": fmt.Sprintf("maxretry = %d", settings.Maxretry),
|
||||
"banaction": fmt.Sprintf("banaction = %s", banaction),
|
||||
"banaction_allports": fmt.Sprintf("banaction_allports = %s", banactionAllports),
|
||||
"chain": fmt.Sprintf("chain = %s", chain),
|
||||
}
|
||||
if settings.BantimeRndtime != "" {
|
||||
keysToUpdate["bantime.rndtime"] = fmt.Sprintf("bantime.rndtime = %s", settings.BantimeRndtime)
|
||||
}
|
||||
defaultKeysOrder := []string{"enabled", "bantime.increment", "ignoreip", "bantime", "findtime", "maxretry", "banaction", "banaction_allports", "chain"}
|
||||
if settings.BantimeRndtime != "" {
|
||||
defaultKeysOrder = append(defaultKeysOrder, "bantime.rndtime")
|
||||
}
|
||||
|
||||
// Track which keys we've updated
|
||||
@@ -1257,7 +1269,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{"enabled", "bantime.increment", "ignoreip", "bantime", "findtime", "maxretry", "banaction", "banaction_allports"} {
|
||||
for _, key := range defaultKeysOrder {
|
||||
newLines = append(newLines, keysToUpdate[key])
|
||||
}
|
||||
newLines = append(newLines, "")
|
||||
@@ -1307,14 +1319,23 @@ func UpdateDefaultSettingsLocal(settings config.AppSettings) error {
|
||||
} else if inDefault {
|
||||
// We're in DEFAULT section - check if this line is a key we need to update
|
||||
keyUpdated := false
|
||||
for key, newValue := range keysToUpdate {
|
||||
// Check if this line contains the key (with or without spaces around =)
|
||||
keyPattern := "^\\s*" + regexp.QuoteMeta(key) + "\\s*="
|
||||
if matched, _ := regexp.MatchString(keyPattern, trimmed); matched {
|
||||
outputLines = append(outputLines, newValue)
|
||||
keysUpdated[key] = true
|
||||
// When user cleared bantime.rndtime, remove the line from config instead of keeping old value
|
||||
if settings.BantimeRndtime == "" {
|
||||
if matched, _ := regexp.MatchString(`^\s*bantime\.rndtime\s*=`, trimmed); matched {
|
||||
keyUpdated = true
|
||||
break
|
||||
// don't append: line is removed
|
||||
}
|
||||
}
|
||||
if !keyUpdated {
|
||||
for key, newValue := range keysToUpdate {
|
||||
// Check if this line contains the key (with or without spaces around =)
|
||||
keyPattern := "^\\s*" + regexp.QuoteMeta(key) + "\\s*="
|
||||
if matched, _ := regexp.MatchString(keyPattern, trimmed); matched {
|
||||
outputLines = append(outputLines, newValue)
|
||||
keysUpdated[key] = true
|
||||
keyUpdated = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if !keyUpdated {
|
||||
@@ -1330,14 +1351,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{"enabled", "bantime.increment", "ignoreip", "bantime", "findtime", "maxretry", "banaction", "banaction_allports"} {
|
||||
for _, key := range defaultKeysOrder {
|
||||
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{"enabled", "bantime.increment", "ignoreip", "bantime", "findtime", "maxretry", "banaction", "banaction_allports"} {
|
||||
for _, key := range defaultKeysOrder {
|
||||
if !keysUpdated[key] {
|
||||
// Find the DEFAULT section and insert after it
|
||||
for i, line := range outputLines {
|
||||
|
||||
Reference in New Issue
Block a user