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.
94 lines
2.7 KiB
Python
94 lines
2.7 KiB
Python
"""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))
|