feat: improve access logging for banned IPs and handle connection resets

This commit is contained in:
Lorenzo Venerandi
2026-03-09 17:59:00 +01:00
parent 68375f6a32
commit 6218a19638
2 changed files with 18 additions and 2 deletions

View File

@@ -129,9 +129,17 @@ def create_app() -> FastAPI:
# Access log middleware (outermost — logs every request with real client IP) # Access log middleware (outermost — logs every request with real client IP)
@application.middleware("http") @application.middleware("http")
async def access_log_middleware(request: Request, call_next): async def access_log_middleware(request: Request, call_next):
response: Response = await call_next(request)
from dependencies import get_client_ip from dependencies import get_client_ip
try:
response: Response = await call_next(request)
except ConnectionResetError:
client_ip = get_client_ip(request)
path = request.url.path
method = request.method
get_access_logger().info(f"[BANNED] [{method}] {client_ip} - {path}")
raise
client_ip = get_client_ip(request) client_ip = get_client_ip(request)
path = request.url.path path = request.url.path
method = request.method method = request.method

View File

@@ -2,6 +2,7 @@
""" """
Middleware for checking if client IP is banned. Middleware for checking if client IP is banned.
Resets the connection for banned IPs instead of sending a response.
""" """
from starlette.middleware.base import BaseHTTPMiddleware from starlette.middleware.base import BaseHTTPMiddleware
@@ -11,6 +12,13 @@ from starlette.responses import Response
from dependencies import get_client_ip from dependencies import get_client_ip
class ConnectionResetResponse(Response):
"""Response that abruptly closes the connection without sending data."""
async def __call__(self, scope, receive, send):
raise ConnectionResetError()
class BanCheckMiddleware(BaseHTTPMiddleware): class BanCheckMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next): async def dispatch(self, request: Request, call_next):
# Skip ban check for dashboard routes # Skip ban check for dashboard routes
@@ -23,7 +31,7 @@ class BanCheckMiddleware(BaseHTTPMiddleware):
tracker = request.app.state.tracker tracker = request.app.state.tracker
if tracker.is_banned_ip(client_ip): if tracker.is_banned_ip(client_ip):
return Response(status_code=500) return ConnectionResetResponse()
response = await call_next(request) response = await call_next(request)
return response return response