Add ensure_jail_configs startup check for required jail config files
On startup BanGUI now verifies that the four fail2ban jail config files required by its two custom jails (manual-Jail and blocklist-import) are present in `$fail2ban_config_dir/jail.d`. Any missing file is created with the correct default content; existing files are never overwritten. Files managed: - manual-Jail.conf (enabled=false template) - manual-Jail.local (enabled=true override) - blocklist-import.conf (enabled=false template) - blocklist-import.local (enabled=true override) The check runs in the lifespan hook immediately after logging is configured, before the database is opened.
This commit is contained in:
93
backend/app/utils/jail_config.py
Normal file
93
backend/app/utils/jail_config.py
Normal file
@@ -0,0 +1,93 @@
|
||||
"""Utilities for ensuring required fail2ban jail configuration files exist.
|
||||
|
||||
BanGUI requires two custom jails — ``manual-Jail`` and ``blocklist-import``
|
||||
— to be present in the fail2ban ``jail.d`` directory. This module provides
|
||||
:func:`ensure_jail_configs` which checks each of the four files
|
||||
(``*.conf`` template + ``*.local`` override) and creates any that are missing
|
||||
with the correct default content.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import structlog
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from pathlib import Path
|
||||
|
||||
log: structlog.stdlib.BoundLogger = structlog.get_logger()
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Default file contents
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
_MANUAL_JAIL_CONF = """\
|
||||
[manual-Jail]
|
||||
|
||||
enabled = false
|
||||
filter = manual-Jail
|
||||
logpath = /remotelogs/bangui/auth.log
|
||||
backend = polling
|
||||
maxretry = 3
|
||||
findtime = 120
|
||||
bantime = 60
|
||||
ignoreip = 127.0.0.0/8 ::1 172.16.0.0/12
|
||||
"""
|
||||
|
||||
_MANUAL_JAIL_LOCAL = """\
|
||||
[manual-Jail]
|
||||
enabled = true
|
||||
"""
|
||||
|
||||
_BLOCKLIST_IMPORT_CONF = """\
|
||||
[blocklist-import]
|
||||
|
||||
enabled = false
|
||||
filter =
|
||||
logpath = /dev/null
|
||||
backend = auto
|
||||
maxretry = 1
|
||||
findtime = 1d
|
||||
bantime = 1w
|
||||
ignoreip = 127.0.0.0/8 ::1 172.16.0.0/12
|
||||
"""
|
||||
|
||||
_BLOCKLIST_IMPORT_LOCAL = """\
|
||||
[blocklist-import]
|
||||
enabled = true
|
||||
"""
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# File registry: (filename, default_content)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
_JAIL_FILES: list[tuple[str, str]] = [
|
||||
("manual-Jail.conf", _MANUAL_JAIL_CONF),
|
||||
("manual-Jail.local", _MANUAL_JAIL_LOCAL),
|
||||
("blocklist-import.conf", _BLOCKLIST_IMPORT_CONF),
|
||||
("blocklist-import.local", _BLOCKLIST_IMPORT_LOCAL),
|
||||
]
|
||||
|
||||
|
||||
def ensure_jail_configs(jail_d_path: Path) -> None:
|
||||
"""Ensure the required fail2ban jail configuration files exist.
|
||||
|
||||
Checks for ``manual-Jail.conf``, ``manual-Jail.local``,
|
||||
``blocklist-import.conf``, and ``blocklist-import.local`` inside
|
||||
*jail_d_path*. Any file that is missing is created with its default
|
||||
content. Existing files are **never** overwritten.
|
||||
|
||||
Args:
|
||||
jail_d_path: Path to the fail2ban ``jail.d`` directory. Will be
|
||||
created (including all parents) if it does not already exist.
|
||||
"""
|
||||
jail_d_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
for filename, default_content in _JAIL_FILES:
|
||||
file_path = jail_d_path / filename
|
||||
if file_path.exists():
|
||||
log.debug("jail_config_already_exists", path=str(file_path))
|
||||
else:
|
||||
file_path.write_text(default_content, encoding="utf-8")
|
||||
log.info("jail_config_created", path=str(file_path))
|
||||
Reference in New Issue
Block a user