fix: capath instead of cafile for all LLM clients
OpenSSL 3.x ignores intermediate CA certs in -CAfile (verify code 20) but correctly builds chains with -CApath (verify code 0). All three clients now use capath: - service.py: ssl.create_default_context(capath=...) - _llm_http.py: verify='/etc/ssl/certs/' - preview_llm_client.py: verify='/etc/ssl/certs/' check_llm_certs.py rewritten for clarity.
This commit is contained in:
@@ -924,24 +924,27 @@ class LLMClient:
|
||||
|
||||
# region LLMClient._get_ssl_verify [TYPE Function]
|
||||
# @PURPOSE Resolve SSL verification flag from environment.
|
||||
# @POST Returns SSLContext with system CA bundle when enabled,
|
||||
# @POST Returns SSLContext with system CA dir when enabled,
|
||||
# False when LLM_SSL_VERIFY env var is "false"/"0"/"no"/"off".
|
||||
# @RATIONALE Возвращаем ssl.SSLContext вместо True, потому что httpx по
|
||||
# умолчанию использует certifi, в котором нет корпоративных CA.
|
||||
# ssl.create_default_context(cafile=...) гарантирует, что используются
|
||||
# сертификаты из системного хранилища (/etc/ssl/certs/ca-certificates.crt),
|
||||
# куда update-ca-certificates и наш fallback добавляют корпоративные CA.
|
||||
# @RATIONALE Используем capath=/etc/ssl/certs/ вместо cafile, потому что
|
||||
# OpenSSL 3.x не использует intermediate CA сертификаты из cafile для
|
||||
# построения цепочки (verify code 20). capath с хеш-симлинками работает
|
||||
# корректно (verify code 0). Оба пути — cafile и capath — указывают на
|
||||
# один и тот же набор сертификатов, но capath правильно обрабатывает
|
||||
# цепочку Root → Policy → Issuing.
|
||||
# @REJECTED verify=<string> отвергнут — httpx 0.28.x депрекейтит строковый
|
||||
# путь в verify=, требует SSLContext.
|
||||
# @REJECTED cafile отвергнут — OpenSSL 3.x не использует intermediate CA
|
||||
# из единого bundle-файла. Только capath с хеш-симлинками даёт code 0.
|
||||
@staticmethod
|
||||
def _get_ssl_verify() -> ssl.SSLContext | bool:
|
||||
raw = os.getenv("LLM_SSL_VERIFY", "true").strip().lower()
|
||||
if raw in ("false", "0", "no", "off"):
|
||||
return False
|
||||
ca_path = "/etc/ssl/certs/ca-certificates.crt"
|
||||
if os.path.exists(ca_path):
|
||||
return ssl.create_default_context(cafile=ca_path)
|
||||
# fallback: если системного CA нет (редко), используем дефолтный
|
||||
ca_dir = "/etc/ssl/certs"
|
||||
if os.path.isdir(ca_dir):
|
||||
return ssl.create_default_context(capath=ca_dir)
|
||||
# fallback: если директории нет (редко), используем дефолтный
|
||||
return ssl.create_default_context()
|
||||
# endregion LLMClient._get_ssl_verify
|
||||
|
||||
|
||||
Reference in New Issue
Block a user