fix(T+托管): 限制健康检查重定向范围
supervisor 的健康探测只允许访问本机地址,避免本机端点重定向到外部网络。\n增加重定向处理器和回归测试,保留现有依赖健康及错误脱敏行为。\n\n影响范围:T+ supervisor 健康检查与运行控制单元测试。\n\nCo-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
1 parent
fc4428abb5
commit
b21dff12f4
2 files changed
+45
-4
No files matched your search
@@ -10,7 +10,7 @@ import time
|
||||
from pathlib import Path
|
||||
from urllib.error import URLError
|
||||
from urllib.parse import urlsplit
|
||||
from urllib.request import urlopen
|
||||
from urllib.request import HTTPRedirectHandler, build_opener
|
||||
from uuid import uuid4
|
||||
|
||||
from sqlalchemy import create_engine, select, text, update
|
||||
@@ -26,6 +26,24 @@ logger = logging.getLogger(__name__)
|
||||
LOCK_NAME = "ys:tplus:supervisor"
|
||||
|
||||
|
||||
class _LocalOnlyRedirectHandler(HTTPRedirectHandler):
|
||||
"""拒绝健康检查从本机地址跳转到外部地址。"""
|
||||
|
||||
def redirect_request(self, req, fp, code, msg, headers, new):
|
||||
parsed = urlsplit(new)
|
||||
if parsed.scheme != "http" or parsed.hostname not in ("localhost", "127.0.0.1", "::1"):
|
||||
return None
|
||||
return super().redirect_request(req, fp, code, msg, headers, new)
|
||||
|
||||
|
||||
_health_opener = build_opener(_LocalOnlyRedirectHandler)
|
||||
|
||||
|
||||
def _open_health(url, *, timeout):
|
||||
return _health_opener.open(url, timeout=timeout)
|
||||
|
||||
|
||||
|
||||
def health_error(settings):
|
||||
"""只访问本机健康端点,禁止通过配置探测外部网络。"""
|
||||
try:
|
||||
@@ -33,7 +51,7 @@ def health_error(settings):
|
||||
parsed = urlsplit(url)
|
||||
if parsed.scheme != "http" or parsed.hostname not in ("localhost", "127.0.0.1", "::1"):
|
||||
return "后端健康检查地址必须是本机 HTTP 地址"
|
||||
with urlopen(url, timeout=3) as response:
|
||||
with _open_health(url, timeout=3) as response:
|
||||
body = json.load(response)
|
||||
data = body.get("data") if isinstance(body, dict) else None
|
||||
if not isinstance(data, dict) or not all(data.get(key) is True for key in ("app", "db", "redis")):
|
||||
|
||||
Reference in new issue
Block a user