Проблема в том, что 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, в котором могут быть некоторые обновления
Предпосылки для этого скрипта:
- У вас есть данные доверенного корневого центра сертификации,
/etc/ssl/certsкак обычно, например, в Ubuntu
- Создайте каталог, в
DIRкотором вы храните 3 файла:
DIR/certificate.crt который содержит сертификат
DIR/certificate.key который содержит секретный ключ для вашего веб-сервиса (без парольной фразы)
DIR/certificate.bundleкоторый содержит CA-Bundle. О том, как подготовить связку, читайте ниже.
- Теперь запустите скрипт:
./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-bundle должен быть составлен в точном соответствии с правильным порядком обработки, это означает, что первый необходимый сертификат (промежуточный сертификат, который подписывает ваш сертификат) идет первым в пакете. Тогда потребуется сертификат с перекрестной подписью.
Обычно ваш 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который является еще одним промежуточным звеном от другого подписанного CA crossigned.crt(вы, вероятно, никогда не увидите такого)
Тогда правильный catбудет выглядеть так:
cat intermediate2.crt intermediate1.crt crossigned.crt crossintermediate.crt > certificate.bundle
А как узнать, какие файлы нужны или нет и в какой последовательности?
Что ж, экспериментируйте, пока checkвсе в порядке. Это похоже на компьютерную головоломку, в которой нужно разгадывать загадку. Каждый. Не замужем. Время. Даже для профи. Но каждый раз, когда вам нужно это делать, вы будете поправляться. Так что вы определенно не одиноки со всей этой болью. Это SSL, понимаешь? SSL, вероятно, является одним из худших проектов, которые я когда-либо видел за более чем 30 лет профессионального системного администрирования. Вы когда-нибудь задумывались, почему криптовалюта не стала мейнстримом за последние 30 лет? Поэтому. 'достаточно.
man verify, я обнаружил, что этот-untrustedпараметр является правильным для использования при указании промежуточного сертификата.