fix: trust docker gateway IP for reverse proxy auth
Deploy Dashboard / deploy (push) Successful in 1m35s

This commit is contained in:
Gan, Jimmy
2026-02-27 23:48:34 +08:00
parent 3888a57642
commit a0354c335b
4 changed files with 26 additions and 4 deletions
+19
View File
@@ -60,3 +60,22 @@ def is_lan_ip(ip_str: str) -> bool:
return False return False
except ValueError: except ValueError:
return False return False
TRUSTED_PROXIES = os.environ.get("TRUSTED_PROXIES", "127.0.0.1,::1,172.16.0.0/12,10.0.0.0/8").split(",")
def is_trusted_proxy(ip_str: str) -> bool:
import ipaddress
try:
ip_obj = ipaddress.ip_address(ip_str)
for subnet_str in TRUSTED_PROXIES:
subnet_str = subnet_str.strip()
if "/" in subnet_str:
if ip_obj in ipaddress.ip_network(subnet_str):
return True
else:
if ip_obj == ipaddress.ip_address(subnet_str):
return True
return False
except ValueError:
return False
+2 -1
View File
@@ -119,7 +119,8 @@ async def health():
@app.get("/api/client-ip") @app.get("/api/client-ip")
async def client_ip(request: Request): async def client_ip(request: Request):
ip = request.client.host ip = request.client.host
if ip in ("127.0.0.1", "::1"): import config
if config.is_trusted_proxy(ip):
forwarded = request.headers.get("x-forwarded-for", "").split(",")[0].strip() forwarded = request.headers.get("x-forwarded-for", "").split(",")[0].strip()
if forwarded: if forwarded:
ip = forwarded ip = forwarded
+3 -2
View File
@@ -113,8 +113,9 @@ async def login(creds: LoginRequest, request: Request):
async def proxy_auth(request: Request): async def proxy_auth(request: Request):
"""Auto-login when Authelia has already authenticated the user via forward-auth. """Auto-login when Authelia has already authenticated the user via forward-auth.
Caddy sets Remote-User header after successful Authelia 2FA verification.""" Caddy sets Remote-User header after successful Authelia 2FA verification."""
# Prevent IP spoofing: ensure proxy traffic is from localhost (Caddy) # Prevent IP spoofing: ensure proxy traffic is from trusted proxy network
if request.client.host not in ("127.0.0.1", "::1"): import config
if not config.is_trusted_proxy(request.client.host):
logger.warning(f"Rejected proxy auth attempt from unauthorized IP: {request.client.host}") logger.warning(f"Rejected proxy auth attempt from unauthorized IP: {request.client.host}")
raise HTTPException(status_code=403, detail="Unauthorized proxy source") raise HTTPException(status_code=403, detail="Unauthorized proxy source")
+2 -1
View File
@@ -117,7 +117,8 @@ def _classify(method, path, status, user):
@router.get("/openclaw-token") @router.get("/openclaw-token")
def openclaw_token(request: Request): def openclaw_token(request: Request):
ip = request.client.host ip = request.client.host
if ip in ("127.0.0.1", "::1"): import config
if config.is_trusted_proxy(ip):
forwarded = request.headers.get("x-forwarded-for", "").split(",")[0].strip() forwarded = request.headers.get("x-forwarded-for", "").split(",")[0].strip()
if forwarded: if forwarded:
ip = forwarded ip = forwarded