Частина посилань на цій сторінці партнерські: якщо ви зареєструєтесь через них, сайт отримає комісію, для вас ціна не змінюється. На ціни й рекомендації це не впливає.

17 жовтня 2026 року дослідник повідомив програми кореневих сертифікатів, що приватні ключі восьми проміжних центрів сертифікації eMudhra скомпрометовані, і довів це найжорсткішим способом: підписав коротке повідомлення кожним із восьми ключів і додав підписи. Перевірити їх може будь-хто за допомогою OpenSSL. Ключі можна було відновити з квітня 2025 року.

Браузери виправили за кілька днів. Firefox і Chrome заблокували проміжні сертифікати 17-го, платформи Microsoft 20-го, продукти Apple 22-го. Те, чим ви переглядаєте сайти, тепер у порядку.

З машинами, якими ви керуєте, інакше. Це чеклист для них, плюс ті частини історії, від яких залежить, що перевіряти. Усе про сам інцидент взято зі сторінки інциденту, яку ми перечитали в день публікації. Чотири тестові адреси з кроку 1 ми запустили на одній із наших машин з Ubuntu 26.04, і всі чотири закінчилися помилкою сертифіката, тобто тим результатом, якого й треба. Кожне середовище виконання на ній ми не перевіряли, і кроки нижче не є звітом про цю роботу.

Що саме зламалося

Вісім проміжних сертифікатів ведуть до коренів, яким довіряють програми кореневих сертифікатів Mozilla, Microsoft, Apple і Chrome. Хто має один із приватних ключів, може випустити сертифікат для будь-якого домену, а клієнт, що досі довіряє проміжному сертифікату, його прийме.

Причину варто запамʼятати. CA згенерував ключі неправильно, тож їх можна відновити з самих сертифікатів. Так було від дня створення сертифікатів, квітня 2025 року. У журналах Certificate Transparency немає записів про ці проміжні сертифікати за цей період, тому клієнти, що вимагають CT, тобто основні браузери, не могли бути атаковані через них. Із клієнтами без перевірки CT інакше, і сторінка інциденту прямо каже, що ніхто не знає, чи користувалися зловмисники цією вадою проти них.

CA відкликав проміжні сертифікати, а програми кореневих сертифікатів розповсюдили відкликання своїми каналами: OneCRL і CRLite у Mozilla, CRLSets у Chrome. Так браузер лишається захищеним без нової збірки. Дуже багато клієнтів не дивляться в жоден із цих каналів.

Два рівні довіри, і зачепило лише один

Більшість посібників із самохостингу змішують їх, тож їх варто розділити.

Ваші сертифікати в порядку. Якщо Caddy, Traefik, acme.sh чи certbot отримують сертифікати в Let’s Encrypt, у них нічого не змінилося. Проміжних сертифікатів eMudhra в цьому ланцюжку немає, а протокол ACME і ключі вашого акаунта до справи не мали жодного стосунку. Оновлення працює далі.

Те, чому довіряють ваші інструменти, і є вразливою частиною. Кожен вихідний HTTPS-запит вашого сервера (git pull, curl до API, встановлення пакета, pull контейнера, вебхук) надійний рівно настільки, наскільки надійне сховище сертифікатів на цій машині. Якщо в ньому досі лежать погані проміжні сертифікати, хтось на мережевому шляху може видати себе за GitHub, ваше дзеркало пакетів чи будь-яке API, і клієнт прийме це без жодного слова.

Це весь ризик, і більша його частина сидить у програмах, що не є браузерами.

Чому «оновити ОС» це ще не все

Браузери відрізняються від решти двома речами.

По-перше, відкликання. Браузери отримують відкликання цих проміжних сертифікатів через OneCRL, CRLite і CRLSets. curl, git, бінарники Go і більшість середовищ виконання не користуються нічим із цього, і для них єдиний засіб це сховище довіри, де проміжних сертифікатів уже немає.

По-друге, Certificate Transparency. Браузери відхиляють сертифікати, яких ніколи не було в журналах. Більшості не браузерних клієнтів це байдуже. Сторінка інциденту для цього тримає два додаткові тестові хости: їхні сертифікати ніколи не потрапляли в CT, тож клієнт, який до них підключається, довіряє поганим проміжним сертифікатам і теж не вимагає CT. Саме цією комбінацією зловмисник може скористатися так, що ніхто не помітить.

Отже, завдання не в одному оновленні, а в одному на кожну програму, що несе власне сховище довіри або успадковує його.

Аудит на 30 хвилин

Запустіть його на кожному сервері, CI-раннері й машині розробника, до яких маєте доступ. Кожен крок це одна-дві команди.

1. Оновити системний бандл CA

Debian і Ubuntu:

sudo apt update && sudo apt upgrade -y ca-certificates

RHEL, Fedora, Alma, Rocky:

sudo dnf upgrade -y ca-certificates

Alpine:

sudo apk upgrade ca-certificates

Виправлені версії пакетів перелічені на сторінці інциденту. Для Debian 12 це 20250419~deb12u2, для Ubuntu 24.04 20260816ubuntu0.24.04.1, для Alpine 20261020-r0. Порівняйте через dpkg -l ca-certificates або apk info ca-certificates, а потім зробіть справжній тест. Помилка сертифіката означає, що цей клієнт не довіряє скомпрометованим проміжним сертифікатам. Успішна відповідь означає, що ви досі під загрозою:

curl https://dv-g3b-emudhra.we-have-a-problem.com/
curl https://dv-g3b-aaa-emudhra.we-have-a-problem.com/
curl https://dv-g3b-noct-emudhra.we-have-a-problem.com/
curl https://dv-g3b-aaa-noct-emudhra.we-have-a-problem.com/

Якщо ви запускаєте Java з пакетів Debian чи Ubuntu, треба ще одне: системне оновлення не оновлює сховище ключів Java через давню помилку в ca-certificates-java. Порада зі сторінки інциденту: створити його заново від імені root:

rm -f /etc/ssl/certs/java/cacerts && update-ca-certificates --fresh

2. Виправити бандли, яких системне оновлення не торкнулося

Кілька середовищ виконання несуть власну копію і не помітять вашого оновлення ca-certificates.

requests у Python читає бандл certifi, а не системне сховище. Виправлена версія certifi 2026.10.19, а сам pip виправлено у 26.2.2:

pip install --upgrade certifi pip

Node.js постачається з власним сховищем коренів і за замовчуванням не читає системне. Виправлені випуски 26.12.1, 24.22.1 і 22.23.4, тож для довгоживучого сервісу на Node потрібен новіший Node, а не новіший ca-certificates. Go на Linux читає системне сховище, але проєкт теж випустив виправлення у 1.27.3 і 1.26.10, а програми на Rust, що вбудовують webpki-roots, треба перезібрати з виправленим crate.

Коли ми дивилися, certbot і containerd на сторінці інциденту ще значилися як очікувані. Перевірте цю сторінку ще раз, перш ніж вважати, що ваша версія покрита.

Усе, що читає системне сховище, однаково треба перезапустити. Сервіс, запущений до оновлення, тримає старе сховище в памʼяті, доки ви його не перезапустите.

3. Знову завантажити або перезібрати образи контейнерів

Образ заморожує свій бандл CA на момент збірки. Якщо його зібрали до того, як дистрибутив випустив видалення, він довіряє проміжним сертифікатам, хоч як оновлено хост.

docker pull debian:bookworm   # або ваш базовий образ
docker compose build --pull   # якщо збираєте власні

Тут і підстава: старий тег ніколи не перезбирають. Якщо у вашому Dockerfile досі стоїть node:20, golang:1.23 чи alpine:3.19, ці рядки вичерпали підтримку, і повторний pull повертає той самий застарілий бандл. Перейдіть на підтримуваний тег. Для образів, які збираєте не ви, перевірте, що видавець випустив новий тег після 20 жовтня. Цей крок більшість пропускає, і саме він захищає контейнери.

4. Оновити застосунки Electron скрізь, де ви розробляєте

Застосунки Electron отримують виправлення лише тоді, коли їх перезбирають на виправленому випуску Electron (виправлені лінійки 44.9.1, 43.8.1 і 42.11.16). Оновлення ОС чи браузера їм нічого не дає. Slack, Discord і все інше на цьому рушії, на вашому комп’ютері й на CI-раннерах, потребує власного оновлення.

Інструменти розробника Apple були окремим випадком: git, curl і python3, що йдуть із macOS, станом на 28 жовтня досі довіряли скомпрометованим сертифікатам, а macOS 27.2 скасувала виправлення, які дехто застосував вручну. На Mac перевіряйте інструменти напряму командами curl вище, а не покладайтеся на версію ОС.

5. Подивитися на раннери, якими CI справді користується

Хмарний раннер, самостійно розгорнутий агент чи контейнер збірки тут є ціллю для атаки на ланцюжок постачання. Якщо зловмисник може видати себе за реєстр пакетів, усе, що цей раннер збирає, у його владі. Перевірте, що образ раннера свіжий, а закріплений базовий образ із кроку 3 оновлено. GitLab Runner 19.5.1 це виправлений випуск, якщо ви користуєтеся ним.

Чого це не торкається

Ця тема набула популярності через multi-perspective validation у Let’s Encrypt, коли контроль над доменом перевіряють із кількох мережевих точок, щоб BGP-перехоплення на одному шляху не обдурило CA і не змусило видати сертифікат на домен, на який він не повинен. Це справжній захист, і він працює на рівні видачі: захищає момент, коли сертифікат запитують.

Проблема eMudhra лежить на рівні довіри. Ключі центру сертифікації скомпрометовані, а це не повʼязано з тим, як перевіряли домени, тож multi-perspective validation цього б не виявила. Ці два рівні легко сплутати. «Let’s Encrypt перевіряє з кількох місць» не привід пропускати аудит вище.

Для вашого власного ACME-стеку все зводиться до трьох речей. Ваші сертифікати не зачеплені, оновлення працюють. Ризик у ваших клієнтах, і виправляє його лише оновлення сховища довіри. І Caddy чи Traefik, що завершують TLS вашим власним сертифікатом, у порядку, а от git, curl, docker і середовища виконання на тому ж сервері й є поверхнею атаки.

Де запускати аудит

Стек, який ви перевіряєте, майже напевно маленький VPS або хост для контейнерів, а кроки вище припускають shell на ньому. Якщо ви ще обираєте машину, бюджетний клас ми протестували й описали в порівнянні VPS. ACME-конфігурація, що обслуговує цей сайт, Caddy і Docker за одним імʼям хоста, описана в посібнику з Caddy у продакшні. Випадок старої машини, де certbot не встановлюється і ви берете оновлення на себе через acme.sh, це той, який більшість самохостерів рано чи пізно успадковує.