Коли внутрішній сервіс чи тестовий стенд використовує сертифікат власного центру сертифікації, curl і системні служби відповідають «unable to get local issuer certificate». Рішення: додати кореневий сертифікат до системного сховища довірених. Нижче: де воно міститься в Debian, Ubuntu та родині RHEL, як його поповнити і чому деякі програми все одно не довіряють. Сертифікати для SSH влаштовано інакше, про них написано в статті SSH-сертифікати та власний CA.
Де лежить сховище
Системне сховище складається з каталогу для ваших файлів і підсумкового набору, який збирає спеціальна команда. Програми читають саме підсумковий набір, тому після копіювання файлу команду потрібно запустити.
| Родина | Тека для власних сертифікатів | Команда | Підсумковий набір |
|---|---|---|---|
| Debian, Ubuntu | /usr/local/share/ca-certificates/ | update-ca-certificates | /etc/ssl/certs/ca-certificates.crt |
| RHEL, AlmaLinux, Rocky | /etc/pki/ca-trust/source/anchors/ | update-ca-trust | /etc/pki/tls/certs/ca-bundle.crt |
Пакет ca-certificates приносить перелік загальновизнаних центрів сертифікації. Ваші файли лежать окремо, і оновлення пакета їх не стирає.
Додаємо сертифікат у Debian і Ubuntu
Потрібен кореневий сертифікат у форматі PEM (текстовий файл із блоком BEGIN CERTIFICATE) і з розширенням .crt: файли з іншим розширенням команда пропускає. Якщо вам видали файл .cer у двійковому форматі DER, спершу перетворіть його. Команда update-ca-certificates має повідомити, що додано один сертифікат.
openssl x509 -inform der -in myca.cer -out myca.crt
openssl x509 -in myca.crt -noout -subject -dates
sudo cp myca.crt /usr/local/share/ca-certificates/myca.crt
sudo update-ca-certificates
Щоб прибрати сертифікат, видаліть файл і перезберіть набір із ключем --fresh.
sudo rm /usr/local/share/ca-certificates/myca.crt
sudo update-ca-certificates --fresh
Додаємо сертифікат у родині RHEL
В AlmaLinux, Rocky Linux та інших системах цієї родини файл кладуть у каталог anchors і запускають update-ca-trust. Розширення .crt і формат PEM підходять і тут.
sudo cp myca.crt /etc/pki/ca-trust/source/anchors/myca.crt
sudo update-ca-trust
Якщо ви видаляєте файл з anchors, запустіть update-ca-trust ще раз, щоб він зник і з підсумкового набору.
Перевірка результату
Запит curl до внутрішньої адреси має повернути код відповіді без скарг на сертифікат, а рядок Verify return code в openssl має показати 0. Якщо помилка лишилася, вивчіть ланцюжок за інструкцією зі статті Як перевірити SSL-сертифікат.
curl -sS -o /dev/null -w "%{http_code}\n" https://internal.example.com/
openssl s_client -connect internal.example.com:443 -servername internal.example.com </dev/null 2>/dev/null | grep "Verify return code"
Чому системне сховище не завжди допомагає
Багато програм приносять власний набір довірених центрів і системного сховища не читають. Типові випадки:
- Java використовує файл cacerts і утиліту keytool, тому для неї сертифікат імпортують окремо;
- Python з бібліотекою requests бере набір із пакета certifi, якщо не задано змінну REQUESTS_CA_BUNDLE;
- Node.js містить вбудований перелік, а власний файл підключається змінною NODE_EXTRA_CA_CERTS;
- Firefox і контейнери Docker тримають власні сховища.
curl --cacert myca.crt https://internal.example.com/
export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt
export NODE_EXTRA_CA_CERTS=/usr/local/share/ca-certificates/myca.crt
sudo keytool -importcert -alias myca -file myca.crt -keystore "$JAVA_HOME/lib/security/cacerts"
Для разового виклику в curl є ключ --cacert. Перевірку вимикати ключами на кшталт -k не варто: вона перестає захищати з'єднання.
Обережно: кореневий сертифікат — це довіра до всього
Доданий кореневий сертифікат дозволяє його власникові випустити сертифікат на будь-яке ім'я, і система визнає його справжнім. Додавайте лише власний центр або той, якому ви повністю довіряєте, і зберігайте закритий ключ у надійному місці. Для публічного сайту власний центр не потрібен: подробиці в статті про типи сертифікатів DV, OV та EV. Прив'язку сертифіката до DNS описує стаття TLSA та DANE.
Часті питання
Де міститься сховище сертифікатів в Ubuntu?
Підсумковий набір лежить у файлі /etc/ssl/certs/ca-certificates.crt, а окремі сертифікати — в каталозі /etc/ssl/certs. Власні файли кладуть у /usr/local/share/ca-certificates/ і потім запускають update-ca-certificates. Редагувати підсумковий набір вручну не можна: під час наступного запуску команди правки зникнуть.
Як додати сертифікат до довірених в Ubuntu?
Покладіть кореневий сертифікат у форматі PEM з розширенням .crt у каталог /usr/local/share/ca-certificates/ і виконайте sudo update-ca-certificates. Команда повідомить, що додано один сертифікат. Після цього curl і системні служби почнуть приймати сертифікати, випущені цим центром, без додаткових ключів.
Чому curl довіряє сертифікату, а Java чи Python ні?
Ці програми мають власні сховища або вбудовані набори центрів. Java читає cacerts, Python з requests використовує пакет certifi, Node.js має вбудований перелік. Вкажіть сертифікат засобами самої програми: через keytool або змінні REQUESTS_CA_BUNDLE і NODE_EXTRA_CA_CERTS.
Чи потрібно перезапускати служби після update-ca-trust?
Сховище читається під час запуску процесу, тому служби, що вже працюють, можуть і далі використовувати старий набір. Перезапустіть ті служби, які звертаються до внутрішніх адрес по HTTPS, і перевірте з'єднання. Для нових процесів, наприклад для curl, перезапуск не потрібен.