131 lines
10 KiB
Markdown
131 lines
10 KiB
Markdown
# 2018-08 · TLS и CA bundle в PHP · тройное ревью
|
||
|
||
Статус: **принят в публикационный слой 31 июля 2026 года**. Пакет не
|
||
перезаписывает `web/data/articles.json`: `web/data/editorial-revisions.mjs`
|
||
накладывает его только по стабильным slug.
|
||
|
||
## Состав партии
|
||
|
||
| Ревизия | Основной текст | Смысловая задача | Визуал | Источники |
|
||
| --- | ---: | --- | --- | ---: |
|
||
| `editorial-2018-08-practice-tls-ca` | 7 816 знаков | Диагностика certificate verification в PHP cURL без снятия защиты | `tls-ca-diagnostic-2018.svg` | 8 |
|
||
| `editorial-2018-08-mechanism-tls-ca` | 7 641 знак | Разделение server chain, CA store, hostname check и SNI | `tls-ca-chain-sni-2018.svg` | 7 |
|
||
| `editorial-2018-08-field-tls-ca` | 8 358 знаков | Контролируемая замена устаревшего trust store | `tls-ca-refresh-plan-2018.svg` | 9 |
|
||
|
||
Во всех трёх ревизиях: 8–9 смысловых `<h2>` до раздела источников, одна
|
||
доступная таблица с `<thead>` и `scope="col"`, один SVG с содержательным `alt`
|
||
и `figcaption`, несколько примеров кода, нумерованный порядок действий,
|
||
ограничения и точный заголовок `<h2>Проверяемые источники</h2>`.
|
||
|
||
## Проход 1 — факты и техника
|
||
|
||
### Что сверено
|
||
|
||
- [Документация cURL о CA certificates](https://curl.se/docs/sslcerts.html)
|
||
подтверждает, что peer verification включена по умолчанию и custom CA store
|
||
задаётся отдельно; ни одна статья не предлагает `CURLOPT_SSL_VERIFYPEER=false`
|
||
как решение.
|
||
- [Документация libcurl о CURLOPT_SSL_VERIFYPEER](https://curl.se/libcurl/c/CURLOPT_SSL_VERIFYPEER.html)
|
||
и [CURLOPT_SSL_VERIFYHOST](https://curl.se/libcurl/c/CURLOPT_SSL_VERIFYHOST.html)
|
||
использована для разделения проверки цепочки и имени хоста. В каждом PHP
|
||
примере установлены `CURLOPT_SSL_VERIFYPEER => true` и
|
||
`CURLOPT_SSL_VERIFYHOST => 2`.
|
||
- [OpenSSL 1.0.2 s_client](https://docs.openssl.org/1.0.2/man1/s_client/)
|
||
использован для фактов о `-servername`, `-showcerts`, `-CAfile` и `-CApath`.
|
||
Текст прямо оговаривает, что `-showcerts` показывает присланный сервером
|
||
список, а не уже проверенную цепочку.
|
||
- [OpenSSL 1.0.2 verify](https://docs.openssl.org/1.0.2/man1/verify/)
|
||
подтверждает различие `-CAfile` (trusted certificates) и `-untrusted`
|
||
(intermediate certificates). Команда в статье разделяет leaf, intermediate
|
||
и trust anchor, а не превращает intermediate в корневое доверие.
|
||
- [PHP curl_version](https://www.php.net/manual/en/function.curl-version.php),
|
||
[curl_error](https://www.php.net/manual/en/function.curl-error.php) и
|
||
[cURL runtime configuration](https://www.php.net/manual/en/curl.configuration.php)
|
||
сверены для диагностики PHP-модуля и абсолютного `curl.cainfo`.
|
||
|
||
### Технические решения ревью
|
||
|
||
- Команды используют `api.partner.example` как шаблон. В статьях нет
|
||
выдуманного вывода `curl`, `s_client` или `openssl verify` и нет утверждения,
|
||
что один код ошибки всегда означает единственную причину.
|
||
- Код сохраняет `curl_errno()` и `curl_error()` до `curl_close()`, а verbose
|
||
trace отмечен как материал закрытого стенда, не публичный лог.
|
||
- В статье о механизме цепочка проверяется отдельно от HTTP и отдельно от
|
||
hostname check. Это не смешивает SNI с проверкой имени.
|
||
- В полевой статье новый bundle — версионный конфигурационный артефакт;
|
||
кандидат проверяется до переключения, а final check выполняется тем же
|
||
PHP-клиентом.
|
||
|
||
### Выполненные проверки
|
||
|
||
```text
|
||
node --check web/scripts/upgrade-2018-08.mjs
|
||
node web/scripts/upgrade-2018-08.mjs --print-revisions | JSON.parse(...)
|
||
dynamic import: revisions export есть, process.exitCode не изменился
|
||
структурная проверка: 3/3 ревизии, 5 000–15 000 знаков, h2/figure/table/code/ol/sources
|
||
negative scan: нет CURLOPT_SSL_VERIFYPEER => false и VERIFYHOST => 0/1
|
||
```
|
||
|
||
Вердикт прохода: **пройдено**. Версионная оговорка сохранена: формулировки
|
||
ошибок и детали TLS backend зависят от связки PHP/libcurl/OpenSSL; инструкции
|
||
собирают её версию до вывода.
|
||
|
||
## Проход 2 — редактура и голос
|
||
|
||
Период — М1, 2018: практик PHP-интеграций расширяет вертикаль от cURL-ошибки к
|
||
серверной цепочке и конфигурации окружения. Словарь ограничен cURL, OpenSSL,
|
||
CA bundle, SNI, hostname, intermediate и конкретными параметрами API. В текст
|
||
не добавлены поздние рамки вроде SLO, Kubernetes, distributed tracing или
|
||
организационной стратегии.
|
||
|
||
| Проверка | Результат |
|
||
| --- | --- |
|
||
| Симптом и цена ошибки в первых 1–2 предложениях | Есть во всех трёх статьях: ложное исправление создаёт риск принятия подменённого узла |
|
||
| Один главный вопрос на текст | Диагностика / механизм / controlled refresh разделены, примеры не дублируют друг друга |
|
||
| Прагматичный маршрут | Каждый раздел ведёт от наблюдения к проверке и действию; финал возвращает критерий готовности |
|
||
| Объём без источников | 7 816 / 7 641 / 8 358, в диапазоне 5 000–15 000 |
|
||
| Шаблонные вводные | Сканер не нашёл «В современном мире», «очень важно», «следует отметить», «просто нужно», «нужно понимать, что» |
|
||
| Границы применимости | Явно названы частный CA, missing intermediate, неверное имя, дата/отзыв/политика и разные TLS backend |
|
||
|
||
Во время этой вычитки сокращены универсальные формулировки: вместо «обновите
|
||
сертификат» указано, какой объект обновляется и чем он проверяется; вместо
|
||
«TLS не работает» названы конкретные ветки — CAfile, server chain, SNI и
|
||
hostname. Тон оставлен спокойным и предметным: «давайте разберём», «сначала
|
||
проверяю», «не смешиваю причины».
|
||
|
||
Вердикт прохода: **пройдено**.
|
||
|
||
## Проход 3 — визуал и выпуск
|
||
|
||
### Визуал
|
||
|
||
- `xmllint --noout` успешно проверил все три SVG.
|
||
- Каждая схема открыта в браузере при ширине 1 280 px. Видимые размеры страницы
|
||
не выходили за viewport; у SVG есть `<title>`, `<desc>` и 20–26 текстовых
|
||
узлов для пояснения собственной схемы.
|
||
- После первого визуального просмотра исправлены переноса длинных названий в
|
||
`tls-ca-diagnostic-2018.svg` и `tls-ca-refresh-plan-2018.svg`; во второй
|
||
схеме сокращена подпись стрелки и перенесена строка, чтобы текст не заходил
|
||
на соседний блок.
|
||
- В HTML статей используются существующие обёртки
|
||
`<div class="table-scroll">`: stylesheet блога даёт им горизонтальную
|
||
прокрутку, а таблицам — `min-width`. Полный mobile-render статьи намеренно
|
||
не запускался: по условиям пакета ревизии не добавлены в data archive. На
|
||
уровне разметки каждая таблица подготовлена для этого стиля.
|
||
|
||
### Выпускной контракт
|
||
|
||
- Скрипт экспортирует ровно три объекта как `revisions`.
|
||
- При `node web/scripts/upgrade-2018-08.mjs --print-revisions` stdout проходит
|
||
JSON.parse и содержит только три заданных slug.
|
||
- При import скрипт не печатает Usage и не меняет `process.exitCode`.
|
||
- Новые файлы ограничены этим review, одним скриптом и тремя SVG; `articles.json`,
|
||
стандарт, очередь, registry, audit-скрипт, Git index/commit/push не менялись.
|
||
|
||
Вердикт прохода: **принято к публикации**. Основной редактор повторно прогнал
|
||
strict audit всех трёх slug и production build после интеграции: сборка прошла
|
||
и сгенерировала 374 статические страницы. Повторный live mobile-render в этой
|
||
среде заблокирован политикой браузера; для таблиц применён уже проверенный
|
||
общий контракт `<div class="table-scroll">` + `min-width`, а отдельные SVG
|
||
прошли XML и авторскую визуальную вычитку.
|