fix(security): funnel公网流量强制校验API_KEY双保险(Tailscale-Funnel-Request头,不可伪造)
This commit is contained in:
+25
-7
@@ -55,13 +55,17 @@ def _is_trusted(ip: str) -> bool:
|
|||||||
return any(addr in net for net in TRUSTED_NETWORKS)
|
return any(addr in net for net in TRUSTED_NETWORKS)
|
||||||
|
|
||||||
|
|
||||||
async def require_api_key(
|
def _is_funnel_request(request: Request) -> bool:
|
||||||
request: Request,
|
"""判断是否 tailscale funnel 公网流量
|
||||||
x_api_key: Optional[str] = Header(default=None, alias="X-API-Key"),
|
|
||||||
) -> None:
|
tailscale serve 转发时会把客户端伪造的 Tailscale-* 头清空后按真实
|
||||||
"""校验 API Key:Tailscale 内网/本机放行,外部来源必须携带有效 Key"""
|
情况设置:tailnet 内无此头,funnel 公网流量为 "?1"(不可伪造)。
|
||||||
if _is_trusted(_client_ip(request)):
|
"""
|
||||||
return
|
return request.headers.get("tailscale-funnel-request") == "?1"
|
||||||
|
|
||||||
|
|
||||||
|
async def _require_key(x_api_key: Optional[str]) -> None:
|
||||||
|
"""按外部来源校验 API Key(可信内网已在调用方排除)"""
|
||||||
if not settings.API_KEY:
|
if not settings.API_KEY:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
@@ -74,6 +78,20 @@ async def require_api_key(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def require_api_key(
|
||||||
|
request: Request,
|
||||||
|
x_api_key: Optional[str] = Header(default=None, alias="X-API-Key"),
|
||||||
|
) -> None:
|
||||||
|
"""校验 API Key:Tailscale 内网/本机放行,外部来源必须携带有效 Key"""
|
||||||
|
# funnel 公网流量:即使来源 IP 恰在 tailnet 网段也强制校验(双保险)
|
||||||
|
if _is_funnel_request(request):
|
||||||
|
await _require_key(x_api_key)
|
||||||
|
return
|
||||||
|
if _is_trusted(_client_ip(request)):
|
||||||
|
return
|
||||||
|
await _require_key(x_api_key)
|
||||||
|
|
||||||
|
|
||||||
async def require_agent_key(
|
async def require_agent_key(
|
||||||
x_agent_key: Optional[str] = Header(default=None, alias="X-Agent-Key"),
|
x_agent_key: Optional[str] = Header(default=None, alias="X-Agent-Key"),
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|||||||
Reference in New Issue
Block a user