問題は、それopenssl -verify
が仕事をしないということです。
Priyadiが述べたように、openssl -verify
最初の自己署名証明書で停止するため、中間証明書が自己署名されることが多いため、実際にはチェーンを検証しません。
本番のWebサービスに証明書ファイルをインストールする前に、証明書ファイルが正しいことを101%確認したいと思います。ここのレシピは、まさにこの飛行前チェックを実行します。
Peterの答えが正しいことに注意してください。ただし、の出力は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などの通常どおり、信頼されたCAルートデータがあります。
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
- 不明な中間証明書、おそらく別のCAによって相互署名されています
- 証明書(
certificate.crt
)
これで、評価は下から上に行われます。つまり、最初に証明書が読み取られ、次に不明な中間証明書が必要です。次に、相互署名証明書がおそらく/etc/ssl/certs
参照され、適切な信頼できる証明書を見つけるために参照されます。
caバンドルは、正確に正しい処理順序で作成する必要があります。つまり、最初に必要な証明書(証明書に署名する中間証明書)がバンドルの最初に来ます。次に、相互署名証明書が必要です。
通常、CA(証明書に署名した機関)は、そのような適切なca-bundle-fileをすでに提供しています。そうでない場合は、必要なすべての中間証明書とcat
それらを1つのファイルにまとめる必要があります(UNIXの場合)。Windowsでは、テキストエディター(などnotepad.exe
)を開いて、証明書をファイルに貼り付けるだけです。
別のものがあります。ファイルはPEM形式である必要があります。一部のCAはDER(バイナリ)形式を発行します。PEMは簡単に見つけられます。ASCIIで読み取り可能です。何かをPEMに変換する方法の詳細については、「。crtを.pemに変換する方法」を参照し、黄色いレンガの道をたどってください。
例:
あなたが持っている:
intermediate2.crt
署名した中間証明書 certificate.crt
intermediate1.crt
歌った別の中間証明書 intermediate2.crt
crossigned.crt
これは、署名された別のCAからの相互署名証明書です intermediate1.crt
crossintermediate.crt
これは、署名した他のCAからの別の中間体crossigned.crt
です(おそらく、そのようなことは決してないでしょう)。
次に、適切なものcat
は次のようになります。
cat intermediate2.crt intermediate1.crt crossigned.crt crossintermediate.crt > certificate.bundle
そして、どのファイルが必要であるか、どのシーケンスで必要かをどのようにして見つけることができますか?
ええと、check
すべてが問題ないと言うまで、実験してください。それは謎を解くコンピューターパズルゲームのようなものです。すべて。シングル。時間。プロでも。しかし、これを行う必要があるたびに良くなります。ですから、あなたはそのような苦痛を伴うだけで決定的に一人ではありません。SSLですよね。SSLはおそらく、30年以上にわたる専門的なシステム管理で見た中で最悪の設計の1つです。過去30年間で暗号化が主流にならない理由を知りましたか?それが理由です。'言っ途切れる。
man verify
、私はことを発見し-untrusted
たパラメータは、中間証明書を指定するときに使用する正しいものです。