Почему привязка OCSP к NGINX для сертификатов DV «buypass» не выполняется без явного объявления корня?

Почему привязка OCSP к NGINX для сертификатов DV «buypass» не выполняется без явного объявления корня?

вкратце

Для сертификатов buypass DV, полученных с помощью certbot, мне нужно явно указать NGINX доверять корневому сертификату buypass, чтобы включить сшивание OCSP. Это не относится к сертификатам Let's Encrypt, и я не могу понять, почему. Я нашел способ (см. ниже), который больше похож на обходной путь, чем на надежное решение. Так что мне интересно, делаю ли я что-то неправильно?


Подробности

Я заметил, что для сертификатов DV buypass.com (GO SSL) извлекается через протокол ACME (поcertbot) NGINX не обеспечивает OCSP «из коробки», даже если такая конфигурация безупречно работает с сертификатами Let's Encrypt:

ssl_stapling on;
ssl_stapling_verify on;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot

Мне нужно сгенерировать новую цепочку, которая включает корневой сертификат ( Buypass_Class_2_Root_CA.pem):

cp /etc/letsencrypt/live/example.com/
cat /etc/ssl/certs/Buypass_Class_2_Root_CA.pem fullchain.pem > ocsp-chain.pem

и явно указать NGINX доверять этой цепочке:

ssl_trusted_certificate /etc/letsencrypt/live/example.com/ocsp-chain.pem;

что меня больше всего сбивает с толку, так это то, что мне не нужно этого делать для сертификатов Let's Encrypt, а NGINX справляется с предоставлением скрепленного OCSPбезнеобходимость создания дополнительного ocsp-chain.pem.


Подробнее (обновление)

Просто некоторые пояснения по сгенерированным цепочкам доверия certbot:

Для Buypass:

/--------- fullchain.pem ---------\    /--- /etc/ssl/certs --\
example.com -> Buypass_Class_2_CA_5 -> Buypass_Class_2_Root_CA
               \---- chain.pem ---/

Для Let’s Encrypt:

/--------- fullchain.pem --------\    / /etc/ssl/certs \
example.com -> Lets_Encrypt_R3.pem -> DST_Root_CA_X3.pem
               \---- chain.pem ---/

Если я выполню следующее:

cd /etc/letsencrypt/live/example.com
# $OSCP_URL is:
#   * Let's Encrypt: http://r3.o.lencr.org
#   * Buypass:       http://ocsp.buypass.com
openssl ocsp -issuer chain.pem -cert fullchain.pem -url "${OCSP_URL}"

Я получаю Response verify OK. Тем не менее, хотяnginx используетopensslпод капотом, который доверяет всем якорям ниже /etc/ssl/certs(в моем случае /usr/lib/ssl/certs -> /etc/ssl/certs), он не может проверить OCSP без вышеупомянутого обходного пути:

2611#2611: OCSP_basic_verify() failed (SSL: error:27069065:OCSP routines:OCSP_basic_verify:certificate verify error:Verify error:unable to get issuer certificate) while requesting certificate status, responder: ocsp.buypass.com, peer: 23.55.161.57:80, certificate: "/etc/letsencrypt/live/example.com/fullchain.pem"

решение1

Обновлять

Оказывается, OpenSSL некорректно обрабатывает ответы OCSP, подписанные уполномоченным органом (не эмитентом). Хотя RFC6960явно указывает, что ответ OCSP должен быть проверен только с использованием сертификата издателя (который также удостоверяет назначенный орган), OpenSSL не придерживается этого и требует от вас явно включить корневой сертификат. Если вы используете CLI, это происходит автоматически (используйте комбинацию -CAfileи -noCApathдля проверки!).

Оригинальный ответ

Мне потребовалось довольно много времени, чтобывыяснить это! Проблема не в NGINX, а в OpenSSL. Я обнаружил, что если OCSP подписан назначенным ответчиком (см.RFC6960), сертификат которого включен в ответ OCSP, OpenSSL не учитывает этот дополнительный сертификат при проверке ответа. Я не могу точно сказать, почему эта проблема не возникает при использовании OpenSSL OCSP CLI (т. е. openssl ocsp -issuer x -cert y -url z).

Связанный контент