Проблема в тому, що openssl -verify
це не справляється.
Як згадував Прияді , openssl -verify
зупиняється на першому самопідписаному сертифікаті, отже, ви не дійсно перевіряєте ланцюг, як часто проміжний сертифікат підписується самостійно.
Я припускаю, що ви хочете бути впевнені на 101%, що файли сертифікатів є правильними, перш ніж спробувати встановити їх у продуктивній веб-службі. Цей рецепт тут виконує саме цю попередню перевірку.
Зауважте, що відповідь Петра правильна , проте висновок openssl -verify
не має поняття, що все справді працює згодом. Так, це може знайти деякі проблеми, але зовсім не всі.
Ось сценарій, який виконує завдання перевірити ланцюжок сертифікатів, перш ніж встановити його в Apache. Можливо, це можна вдосконалити за допомогою якоїсь більш містичної магії OpenSSL, але я не гуру OpenSSL і наступні роботи:
#!/bin/bash
# This Works is placed under the terms of the Copyright Less License,
# see file COPYRIGHT.CLL. USE AT OWN RISK, ABSOLUTELY NO WARRANTY.
#
# COPYRIGHT.CLL can be found at http://permalink.de/tino/cll
# (CLL is CC0 as long as not covered by any Copyright)
OOPS() { echo "OOPS: $*" >&2; exit 23; }
PID=
kick() { [ -n "$PID" ] && kill "$PID" && sleep .2; PID=; }
trap 'kick' 0
serve()
{
kick
PID=
openssl s_server -key "$KEY" -cert "$CRT" "$@" -www &
PID=$!
sleep .5 # give it time to startup
}
check()
{
while read -r line
do
case "$line" in
'Verify return code: 0 (ok)') return 0;;
'Verify return code: '*) return 1;;
# *) echo "::: $line :::";;
esac
done < <(echo | openssl s_client -verify 8 -CApath /etc/ssl/certs/)
OOPS "Something failed, verification output not found!"
return 2
}
ARG="${1%.}"
KEY="$ARG.key"
CRT="$ARG.crt"
BND="$ARG.bundle"
for a in "$KEY" "$CRT" "$BND"
do
[ -s "$a" ] || OOPS "missing $a"
done
serve
check && echo "!!! =========> CA-Bundle is not needed! <========"
echo
serve -CAfile "$BND"
check
ret=$?
kick
echo
case $ret in
0) echo "EVERYTHING OK"
echo "SSLCertificateKeyFile $KEY"
echo "SSLCertificateFile $CRT"
echo "SSLCACertificateFile $BND"
;;
*) echo "!!! =========> something is wrong, verification failed! <======== ($ret)";;
esac
exit $ret
Зауважте, що результат після EVERYTHING OK
- це налаштування Apache, тому що люди, які використовують NginX
або, haproxy
як правило, також можуть чудово це читати та розуміти;)
Існує GitHub Gist цього, який може мати деякі оновлення
Передумови цього сценарію:
- У вас є довірені кореневі дані CA,
/etc/ssl/certs
як зазвичай, наприклад, на Ubuntu
- Створіть каталог,
DIR
де зберігаються 3 файли:
DIR/certificate.crt
який містить сертифікат
DIR/certificate.key
який містить секретний ключ для вашого веб-сервісу (без парольної фрази)
DIR/certificate.bundle
який містить пакет CA. Про те, як приготувати заготовку, дивіться нижче.
- Тепер запустіть скрипт:
./check DIR/certificate
(це передбачає, що сценарій названий check
у поточному каталозі)
- Існує дуже малоймовірний випадок, коли сценарій виводить
CA-Bundle is not needed
. Це означає, що ви (читайте /etc/ssl/certs/
:) вже довіряєте сертифікату підписання. Але це вкрай малоймовірно в WWW.
- Для цього тестовий порт 4433 повинен бути використаний на вашій робочій станції. І краще лише запустити це в безпечному середовищі, оскільки він відкриє порт 4433 для громадськості, який, можливо, побачить зовнішні з'єднання у ворожій обстановці.
Як створити certificate.bundle
файл?
У WWW ланцюжок довіри зазвичай виглядає так:
- довірений сертифікат від
/etc/ssl/certs
- невідомі проміжні сертифікати, можливо перехресні підписані іншим ЦА
- ваш сертифікат (
certificate.crt
)
Тепер оцінка проводиться знизу вгору, це означає, що спочатку читається ваш сертифікат, потім потрібен невідомий проміжний сертифікат, потім, можливо, перехресний сертифікат, а потім /etc/ssl/certs
проводиться консультація для пошуку належного довіреного сертифіката.
Пакет ca повинен бути складений у правильному порядку обробки, це означає, що перший необхідний сертифікат (проміжний сертифікат, який підписує ваш сертифікат) надходить спочатку в комплект. Тоді потрібен перехресний підпис.
Зазвичай ваш CA (орган, який підписав ваш сертифікат) вже надасть такий правильний файл ca-bundle. Якщо ні, вам потрібно підібрати всі необхідні проміжні сертифікати та cat
разом їх в один файл (на Unix). У Windows ви можете просто відкрити текстовий редактор (як notepad.exe
) і вставити сертифікати у файл, перший необхідний зверху та наступний за іншими.
Є інша річ. Файли повинні бути у форматі PEM. Деякі ЦА видають формат DER (двійковий). PEM легко помітити: він читається на ASCII. Докладніше про те, як перетворити щось у PEM, див. Як перетворити .crt у .pem та слідувати дорозі жовтої цегли.
Приклад:
Ти маєш:
intermediate2.crt
проміжний сертифікат, який підписав ваш certificate.crt
intermediate1.crt
ще один проміжний церт, який співав intermediate2.crt
crossigned.crt
що є перехресним підписом від іншого ЦА, який підписав intermediate1.crt
crossintermediate.crt
що є ще одним посередником від іншого підписаного ЦА crossigned.crt
(ви, мабуть, такого ніколи не побачите)
Тоді власне cat
виглядатиме так:
cat intermediate2.crt intermediate1.crt crossigned.crt crossintermediate.crt > certificate.bundle
І як можна дізнатися, які файли потрібні чи ні та в якій послідовності?
Ну, експериментуйте, поки check
вам не скажуть, що все в порядку. Це як комп'ютерна гра-головоломка для розгадування загадки. Кожен. Неодружений Час. Навіть для плюсів. Але ви будете ставати кращими щоразу, коли вам це потрібно зробити. Тож ви, безумовно, не самотні з усім цим болем. Це SSL, знаєте? SSL - це, мабуть, одна з найгірших конструкцій, яку я коли-небудь бачив за 30 років професійного адміністрування системи. Ніколи не замислювалися, чому криптовалюта не стала мейнстрімом за останні 30 років? Ось чому. 'Нафф сказав.
man verify
, я виявив, що-untrusted
параметр є правильним, який слід використовувати під час визначення проміжного сертифіката.