Problemem jest openssl -verify
to nie działa.
Jak wspomniała Priyadi , openssl -verify
zatrzymuje się na pierwszym samopodpisanym certyfikacie, dlatego tak naprawdę nie weryfikujesz łańcucha, ponieważ często certyfikat pośredni jest samopodpisany.
Zakładam, że chcesz mieć 101% pewności, że pliki certyfikatów są poprawne, zanim spróbujesz je zainstalować w produktywnej usłudze sieciowej. Ten przepis tutaj przeprowadza dokładnie tę kontrolę przed lotem.
Proszę zauważyć, że odpowiedź Piotra jest poprawna , jednak wynik openssl -verify
nie jest wskazówką, że wszystko naprawdę działa później. Tak, może napotkać pewne problemy, ale nie wszystkie.
Oto skrypt, który wykonuje zadanie weryfikacji łańcucha certyfikatów przed zainstalowaniem go w Apache. Być może można to ulepszyć za pomocą bardziej mistycznej magii OpenSSL, ale nie jestem guru OpenSSL i następujące prace:
#!/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
Zwróć uwagę, że dane wyjściowe po EVERYTHING OK
to ustawienie Apache, ponieważ ludzie używający NginX
lub haproxy
zwykle potrafią to doskonale przeczytać i zrozumieć;)
Istnieje GitHub Gist tego, który może zawierać pewne aktualizacje
Wymagania wstępne tego skryptu:
- Masz zaufane dane głównego urzędu certyfikacji w
/etc/ssl/certs
jak zwykle, na przykład w systemie Ubuntu
- Utwórz katalog
DIR
którym przechowujesz 3 pliki:
DIR/certificate.crt
który zawiera certyfikat
DIR/certificate.key
który zawiera tajny klucz do Twojej usługi internetowej (bez hasła)
DIR/certificate.bundle
który zawiera pakiet CA. O tym, jak przygotować pakiet, patrz poniżej.
- Teraz uruchom skrypt:
./check DIR/certificate
(przy założeniu, że skrypt ma nazwęcheck
w bieżącym katalogu)
- Istnieje bardzo mało prawdopodobny przypadek, że skrypt wyświetli wynik
CA-Bundle is not needed
. Oznacza to, że ty (czytaj:/etc/ssl/certs/
:) już ufasz certyfikatowi podpisującemu. Ale jest to mało prawdopodobne w sieci WWW.
- Na potrzeby tego testu port 4433 musi być nieużywany na stacji roboczej. I lepiej uruchamiać to tylko w bezpiecznym środowisku, ponieważ otwiera port 4433 wkrótce dla publiczności, która może zobaczyć obce połączenia w wrogim środowisku.
Jak stworzyć certificate.bundle
plik?
W sieci WWW łańcuch zaufania zwykle wygląda następująco:
- zaufany certyfikat od
/etc/ssl/certs
- nieznane certyfikaty pośrednie, prawdopodobnie podpisane krzyżowo przez inny CA
- twój certyfikat (
certificate.crt
)
Teraz ocena odbywa się od dołu do góry, co oznacza, że najpierw czytany jest twój certyfikat, potem potrzebny jest nieznany certyfikat pośredni, potem być może certyfikat cross-podpisujący, a następnie /etc/ssl/certs
konsultowany jest w celu znalezienia odpowiedniego zaufanego certyfikatu.
Ca-bundle musi być skomponowane w dokładnie odpowiedniej kolejności przetwarzania, co oznacza, że pierwszy potrzebny certyfikat (certyfikat pośredni, który podpisuje Twój certyfikat) jest na pierwszym miejscu w pakiecie. Wtedy potrzebny jest certyfikat do podpisu krzyżowego.
Zwykle Twój CA (urząd, który podpisał Twój certyfikat) dostarcza już taki właściwy plik ca-bundle. Jeśli nie, musisz zebrać wszystkie potrzebne certyfikaty pośrednie i cat
zebrać je razem w jednym pliku (w systemie Unix). W systemie Windows możesz po prostu otworzyć edytor tekstu (np. notepad.exe
) I wkleić certyfikaty do pliku, pierwszy potrzebny na górze i po pozostałych.
Jest jeszcze jedna rzecz. Pliki muszą być w formacie PEM. Niektóre urzędy certyfikacji wydają format DER (binarny). PEM jest łatwy do wykrycia: jest czytelny w ASCII. Aby dowiedzieć się, jak przekonwertować coś na PEM, zobacz Jak przekonwertować .crt na .pem i podążaj żółtą ceglaną drogą.
Przykład:
Ty masz:
intermediate2.crt
certyfikat pośredni, który podpisał twój certificate.crt
intermediate1.crt
kolejny certyfikat pośredni, który spalił intermediate2.crt
crossigned.crt
który jest certyfikatem do podpisywania krzyżowego z innego urzędu certyfikacji, który podpisał intermediate1.crt
crossintermediate.crt
który jest kolejnym pośrednikiem z innego CA, który podpisał crossigned.crt
(prawdopodobnie nigdy czegoś takiego nie zobaczysz)
Wtedy właściwy cat
wyglądałby tak:
cat intermediate2.crt intermediate1.crt crossigned.crt crossintermediate.crt > certificate.bundle
Jak możesz dowiedzieć się, które pliki są potrzebne, a które nie iw jakiej kolejności?
Cóż, eksperymentuj, dopóki nie check
powie ci, że wszystko jest w porządku. To jak gra logiczna na komputerze, w której rozwiązuje się zagadkę. Każdy. Pojedynczy. Czas. Nawet dla profesjonalistów. Ale za każdym razem, gdy będziesz tego potrzebować, będziesz coraz lepszy. Więc definitywnie nie jesteś sam z całym tym bólem. To SSL, wiesz? SSL to prawdopodobnie jeden z najgorszych projektów, jakie widziałem w ciągu ponad 30 lat profesjonalnej administracji systemem. Czy zastanawiałeś się kiedyś, dlaczego kryptowaluty nie stały się głównym nurtem w ciągu ostatnich 30 lat? Dlatego. - powiedział nuff.
man verify
stwierdziłem, że-untrusted
parametr jest prawidłowy do użycia podczas określania certyfikatu pośredniego.