fix(security): harden Redis auth, restrict /metrics, document Gitea port fix
Some checks failed
Some checks failed
- Add Redis password via REDIS_PASSWORD env var (--requirepass flag) - Update all REDIS_URL and REDIS_ADDR references to include password - Restrict /metrics endpoint to localhost and Docker internal networks (403 for external requests) - Document Gitea port 3000 localhost binding fix (must be applied manually on server) - Add REDIS_PASSWORD to .env.example Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -34,7 +34,8 @@ from datetime import UTC, datetime
|
||||
from enum import Enum
|
||||
from typing import Any
|
||||
|
||||
from fastapi import APIRouter, Response
|
||||
from fastapi import APIRouter, Request, Response
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -538,12 +539,20 @@ async def readiness_check() -> dict[str, Any]:
|
||||
|
||||
|
||||
@health_router.get("/metrics")
|
||||
async def metrics_endpoint() -> Response:
|
||||
async def metrics_endpoint(request: Request) -> Response:
|
||||
"""
|
||||
Prometheus metrics endpoint.
|
||||
|
||||
Returns metrics in Prometheus text format for scraping.
|
||||
Restricted to localhost and Docker internal networks only.
|
||||
"""
|
||||
client_ip = request.client.host if request.client else None
|
||||
allowed_prefixes = ("127.", "10.", "172.16.", "172.17.", "172.18.", "172.19.",
|
||||
"172.20.", "172.21.", "172.22.", "172.23.", "172.24.",
|
||||
"172.25.", "172.26.", "172.27.", "172.28.", "172.29.",
|
||||
"172.30.", "172.31.", "192.168.", "::1")
|
||||
if not client_ip or not client_ip.startswith(allowed_prefixes):
|
||||
return JSONResponse(status_code=403, content={"detail": "Forbidden"})
|
||||
content = metrics_registry.generate_latest()
|
||||
return Response(
|
||||
content=content,
|
||||
|
||||
Reference in New Issue
Block a user