Vấn đề là, điều openssl -verify
đó không làm được việc.
Như Priyadi đã đề cập , openssl -verify
dừng lại ở chứng chỉ tự ký đầu tiên, do đó bạn không thực sự xác minh chuỗi, vì thông thường chứng chỉ trung gian là tự ký.
Tôi giả sử rằng bạn muốn chắc chắn 101%, rằng các tệp chứng chỉ là chính xác trước khi bạn cố gắng cài đặt chúng trong dịch vụ web hiệu quả. Công thức này ở đây thực hiện chính xác kiểm tra trước chuyến bay này.
Xin lưu ý rằng câu trả lời của Peter là chính xác , tuy nhiên đầu ra của openssl -verify
không có manh mối nào cho thấy mọi thứ thực sự hoạt động sau đó. Vâng, nó có thể tìm thấy một số vấn đề, nhưng không phải tất cả.
Đây là một kịch bản thực hiện công việc xác minh chuỗi chứng chỉ trước khi bạn cài đặt nó vào Apache. Có lẽ điều này có thể được tăng cường với một số phép thuật OpenSSL huyền bí hơn, nhưng tôi không phải là bậc thầy về OpenSSL và các tác phẩm sau:
#!/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
Lưu ý rằng đầu ra sau EVERYTHING OK
là cài đặt Apache, bởi vì mọi người sử dụng NginX
hoặc haproxy
thường có thể đọc và hiểu điều này một cách hoàn hảo;)
Có một GitHub Gist về điều này có thể có một số cập nhật
Điều kiện tiên quyết của kịch bản này:
- Bạn có dữ liệu gốc CA đáng tin cậy
/etc/ssl/certs
như bình thường, ví dụ như trên Ubuntu
- Tạo một thư mục
DIR
nơi bạn lưu trữ 3 tệp:
DIR/certificate.crt
trong đó có chứng chỉ
DIR/certificate.key
có chứa khóa bí mật cho dịch vụ web của bạn (không có cụm mật khẩu)
DIR/certificate.bundle
trong đó có gói CA-Bundle. Về cách chuẩn bị bó, xem bên dưới.
- Bây giờ hãy chạy tập lệnh:
./check DIR/certificate
(điều này giả sử rằng tập lệnh được đặt tên check
trong thư mục hiện tại)
- Có một trường hợp rất khó xảy ra là kịch bản đầu ra
CA-Bundle is not needed
. Điều này có nghĩa là bạn (đọc /etc/ssl/certs/
:) đã tin tưởng vào chứng chỉ ký. Nhưng điều này rất khó xảy ra trong WWW.
- Đối với cổng kiểm tra này, 4433 phải không được sử dụng trên máy trạm của bạn. Và tốt hơn là chỉ chạy cái này trong một môi trường an toàn, vì nó sẽ mở cổng 4433 cho công chúng, điều này có thể thấy các kết nối nước ngoài trong một môi trường thù địch.
Làm thế nào để tạo certificate.bundle
tập tin?
Trong WWW, chuỗi tin cậy thường trông như thế này:
- chứng chỉ tin cậy từ
/etc/ssl/certs
- (các) chứng chỉ trung gian không xác định, có thể được ký bởi CA khác
- chứng chỉ của bạn (
certificate.crt
)
Bây giờ, việc đánh giá diễn ra từ dưới lên trên, điều này có nghĩa là, đầu tiên, chứng chỉ của bạn được đọc, sau đó là chứng chỉ trung gian không xác định, sau đó có lẽ là chứng chỉ ký chéo và sau đó /etc/ssl/certs
được tư vấn để tìm chứng chỉ tin cậy phù hợp.
Gói ca phải được tạo thành chính xác theo thứ tự xử lý đúng, điều này có nghĩa là chứng chỉ cần thiết đầu tiên (chứng chỉ trung gian ký chứng chỉ của bạn) xuất hiện đầu tiên trong gói. Sau đó, chứng nhận chữ ký chéo là cần thiết.
Thông thường CA của bạn (cơ quan đã ký chứng chỉ của bạn) sẽ cung cấp một tệp ca-bundle thích hợp như vậy. Nếu không, bạn cần chọn tất cả các chứng chỉ trung gian cần thiết và cat
chúng cùng nhau thành một tệp duy nhất (trên Unix). Trên Windows, bạn có thể chỉ cần mở trình soạn thảo văn bản (như notepad.exe
) và dán chứng chỉ vào tệp, cái đầu tiên cần thiết ở trên và theo sau những cái khác.
Có một điều khác. Các tập tin cần phải ở định dạng PEM. Một số CA phát hành định dạng DER (nhị phân). PEM rất dễ nhận ra: Nó có thể đọc được ASCII. Để biết cách chuyển đổi một cái gì đó thành PEM, hãy xem Cách chuyển đổi .crt sang .pem và đi theo con đường gạch màu vàng.
Thí dụ:
Bạn có:
intermediate2.crt
chứng chỉ trung gian đã ký certificate.crt
intermediate1.crt
một chứng chỉ trung gian khác, được hát intermediate2.crt
crossigned.crt
đó là một chứng chỉ ký chéo từ một CA khác, đã ký intermediate1.crt
crossintermediate.crt
đó là một trung gian khác từ CA khác đã ký crossigned.crt
(có thể bạn sẽ không bao giờ thấy điều đó)
Sau đó, sự phù hợp cat
sẽ như thế này:
cat intermediate2.crt intermediate1.crt crossigned.crt crossintermediate.crt > certificate.bundle
Và làm thế nào bạn có thể tìm ra những tập tin nào là cần thiết hay không và theo trình tự nào?
Vâng, thử nghiệm, cho đến khi check
cho bạn biết tất cả mọi thứ là OK. Nó giống như một trò chơi giải đố trên máy tính để giải câu đố. Mỗi. Độc thân. Thời gian. Ngay cả cho thuận. Nhưng bạn sẽ trở nên tốt hơn mỗi khi bạn cần làm điều này. Vì vậy, bạn chắc chắn không cô đơn với tất cả nỗi đau đó. Đó là SSL, bạn biết không? SSL có lẽ là một trong những thiết kế tồi tệ nhất tôi từng thấy trong hơn 30 năm quản trị hệ thống chuyên nghiệp. Bạn có bao giờ tự hỏi tại sao tiền điện tử không trở thành xu hướng trong 30 năm qua không? Đó là lý do tại sao. 'nuff nói.
man verify
, tôi thấy rằng-untrusted
tham số này là tham số chính xác để sử dụng khi chỉ định chứng chỉ trung gian.