---
name: ru-gov-ca-cert-missing-macos-python
description: "Российские госсайты/банки (T-Bank API и подобные) отдают TLS-сертификат от НУЦ Минцифры, которого нет в доверенном наборе macOS/Python — выглядит как перехват VPN, но им не является"
metadata: 
  node_type: memory
  type: project
  originSessionId: 6f344612-b945-4107-b457-8ad2163cd988
  modified: 2026-08-03T18:02:13.564Z
---

Запрос к российскому банку/госсервису (`invest-public-api.tinkoff.ru` и
вероятно другие `*.tinkoff.ru`, возможно другие RU-банки/госсайты) падает с
`SSL certificate problem: self signed certificate in certificate chain` —
хотя сертификат легитимный (`CN=*.tinkoff.ru`, `O=TBank`), просто выпущен
российским НУЦ Минцифры («Russian Trusted Sub CA» / «Russian Trusted Root
CA»), которого нет в доверенном наборе macOS/Python по умолчанию.

**Почему легко перепутать с перехватом VPN/прокси:** симптом идентичен
MITM-перехвату (self-signed в цепочке). Проверка перед тем как чинить VPN:
`route get <ip хоста>` — если и проблемный, и заведомо рабочий хост (напр.
`iss.moex.com`) идут через ОДИН интерфейс без VPN-туннеля, и/или VPN сам
`(Disconnected)` (`scutil --nc list`) — дело не в VPN.

**Диагностика:** `openssl s_client -connect host:443 -servername host | openssl x509 -noout -issuer` — если issuer содержит «Russian Trusted» или
«Ministry of Digital Development» — это оно.

**Фикс (официальный бандл):** `https://gu-st.ru/content/lending/russian_trusted_root_ca_pem.crt`
и `.../russian_trusted_sub_ca_pem.crt` (Госуслуги). **Ловушка:** файлы
приходят с CRLF-концами строк — строгий Apple LibreSSL не парсит
(`error setting certificate verify locations` / `bad end line`). Почистить
`tr -d '\r'` + гарантировать `\n` в конце файла перед конкатенацией/
использованием, иначе `--cacert`/`load_verify_locations` тихо не грузит файл.

**В Python-коде:** НЕ трогать системный Keychain (широкий blast radius на
все приложения) — догрузить бандл поверх штатного набора в самом клиенте:
```python
ctx = ssl.create_default_context()
ctx.load_verify_locations(cafile="russian_trusted_ca_bundle.pem")
connector = aiohttp.TCPConnector(ssl=ctx)
```
Реализовано в investpilot: `src/investpilot/marketdata/tinvest_client.py`,
`marketdata/certs/russian_trusted_ca_bundle.pem`. См. [[investpilot_liquidity_gate]] project doc,
Obsidian `Projects/investpilot/Decisions.md` D51.

**How to apply:** если в другом проекте на этой же инфраструктуре (mac mini
или где угодно на macOS) вылезет TLS-ошибка при обращении к российскому
банку/госсайту — первым делом проверить issuer сертификата, а не грешить на
VPN/прокси.
