Add better jail configuration: file CRUD, enable/disable, log paths
Task 4 (Better Jail Configuration) implementation:
- Add fail2ban_config_dir setting to app/config.py
- New file_config_service: list/view/edit/create jail.d, filter.d, action.d files
with path-traversal prevention and 512 KB content size limit
- New file_config router: GET/PUT/POST endpoints for jail files, filter files,
and action files; PUT .../enabled for toggle on/off
- Extend config_service with delete_log_path() and add_log_path()
- Add DELETE /api/config/jails/{name}/logpath and POST /api/config/jails/{name}/logpath
- Extend geo router with re-resolve endpoint; add geo_re_resolve background task
- Update blocklist_service with revised scheduling helpers
- Update Docker compose files with BANGUI_FAIL2BAN_CONFIG_DIR env var and
rw volume mount for the fail2ban config directory
- Frontend: new Jail Files, Filters, Actions tabs in ConfigPage; file editor
with accordion-per-file, editable textarea, save/create; add/delete log paths
- Frontend: types in types/config.ts; API calls in api/config.ts and api/endpoints.ts
- 63 new backend tests (test_file_config_service, test_file_config, test_geo_re_resolve)
- 6 new frontend tests in ConfigPageLogPath.test.tsx
- ruff, mypy --strict, tsc --noEmit, eslint: all clean; 617 backend tests pass
This commit is contained in:
@@ -33,8 +33,21 @@ from starlette.middleware.base import BaseHTTPMiddleware
|
||||
|
||||
from app.config import Settings, get_settings
|
||||
from app.db import init_db
|
||||
from app.routers import auth, bans, blocklist, config, dashboard, geo, health, history, jails, server, setup
|
||||
from app.tasks import blocklist_import, geo_cache_flush, health_check
|
||||
from app.routers import (
|
||||
auth,
|
||||
bans,
|
||||
blocklist,
|
||||
config,
|
||||
dashboard,
|
||||
file_config,
|
||||
geo,
|
||||
health,
|
||||
history,
|
||||
jails,
|
||||
server,
|
||||
setup,
|
||||
)
|
||||
from app.tasks import blocklist_import, geo_cache_flush, geo_re_resolve, health_check
|
||||
from app.utils.fail2ban_client import Fail2BanConnectionError, Fail2BanProtocolError
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -140,6 +153,15 @@ async def _lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
|
||||
geo_service.init_geoip(settings.geoip_db_path)
|
||||
await geo_service.load_cache_from_db(db)
|
||||
|
||||
# Log unresolved geo entries so the operator can see the scope of the issue.
|
||||
async with db.execute(
|
||||
"SELECT COUNT(*) FROM geo_cache WHERE country_code IS NULL"
|
||||
) as cur:
|
||||
row = await cur.fetchone()
|
||||
unresolved_count: int = int(row[0]) if row else 0
|
||||
if unresolved_count > 0:
|
||||
log.warning("geo_cache_unresolved_ips", unresolved=unresolved_count)
|
||||
|
||||
# --- Background task scheduler ---
|
||||
scheduler: AsyncIOScheduler = AsyncIOScheduler(timezone="UTC")
|
||||
scheduler.start()
|
||||
@@ -154,6 +176,9 @@ async def _lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
|
||||
# --- Periodic geo cache flush to SQLite ---
|
||||
geo_cache_flush.register(app)
|
||||
|
||||
# --- Periodic re-resolve of NULL-country geo entries ---
|
||||
geo_re_resolve.register(app)
|
||||
|
||||
log.info("bangui_started")
|
||||
|
||||
try:
|
||||
@@ -375,6 +400,7 @@ def create_app(settings: Settings | None = None) -> FastAPI:
|
||||
app.include_router(bans.router)
|
||||
app.include_router(geo.router)
|
||||
app.include_router(config.router)
|
||||
app.include_router(file_config.router)
|
||||
app.include_router(server.router)
|
||||
app.include_router(history.router)
|
||||
app.include_router(blocklist.router)
|
||||
|
||||
Reference in New Issue
Block a user