Вопрос или проблема
Документация для ssl_client_certificate
гласит:
Указывает файл с сертификатами доверенных центров сертификации в формате PEM, используемыми для проверки клиентских сертификатов и ответов OCSP, если включен
ssl_stapling
.Список сертификатов будет отправлен клиентам. Если это нежелательно, можно использовать директиву
ssl_trusted_certificate
.
Почему этот список отправляется клиентам? Я думал, что процесс проверки клиента предоставляет клиенту возможность отправить свой сертификат (и промежуточные) на сервер для проверки. Это неэффективно, если файл, на который указывает это свойство, велик?
С другой стороны, говорится, что нужно использовать ssl_trusted_certificate
, если вы не хотите отправлять сертификаты клиенту. Если я удалю ssl_client_certificate
и установлю только ssl_trusted_certificate
, то nginx не запустится, так как у меня стоит ssl_verify_client on;
В рамках рукопожатия TLS сервер (если настроен на необходимость аутентификации клиента с помощью сертификатов X.509) отправляет запрос на сертификат обратно клиенту. Часть этого запроса — это список сертификатов CA, которым доверяет сервер. Ожидается, что клиент отправит сертификат аутентификации клиента, который включает один из сертификатов CA в этом списке.
Если задуматься, то не имеет смысла, чтобы клиент отправлял сертификат, если его не может проверить сервер, поэтому имеет смысл, что сервер отправляет список доверенных сертификатов CA. Для клиента было бы неэффективно отправлять сертификаты на сервер, если сервер не доверяет им. Это особенно актуально для клиента, у которого много сертификатов — ему пришлось бы отправлять их все в надежде, что один из них будет доверен сервером.
nginx
генерирует этот список из файла сертификатов, на который указывает ssl_client_certificate
. Вам нужно отправить этот список или отключить ssl_verify_client
.
Также обратите внимание, что ssl_trusted_certificate
будет проверять клиентские сертификаты, но сертификаты в файле, на который указывает эта директива, не отправляются клиенту в рамках рукопожатия TLS. Вместо этого эти сертификаты CA могут быть использованы для проверки ответов OCSP, когда настроено OCSP stapling.
Вы можете прочитать об этом в RFC 5246, раздел 7.4.4, и пока вы там, вы можете прочитать все другие подробности рукопожатия TLS.
С TLS 1.1+ отправка CA в запросе сертификата TLS от сервера к клиенту во время mTLS не является обязательной. Это также делает директиву ssl_client_certificate необязательной в Nginx.
Это изменение будет доступно в Nginx 1.28.0, где можно использовать только ssl_trusted_certificate с включенным ssl_verify_client;
Ответ или решение
Вопрос по верификации клиентских сертификатов в Nginx действительно вызывает интерес и требует разъяснения различий между директивами ssl_client_certificate
и ssl_trusted_certificate
.
Директива ssl_client_certificate
указывает файл с доверенными сертификатами удостоверяющих центров (CA) в формате PEM, которые используются для проверки клиентских сертификатов и ответов OCSP, если включен ssl_stapling
. Когда сервер, настроенный на требование клиентской аутентификации через X.509 сертификаты, отправляет клиенту запрос на сертификат (Certificate Request) в процессе рукопожатия TLS, он включает в этот запрос список CA, которым он доверяет. Клиентский сертификат должен быть выдан одним из этих CA, чтобы сервер мог его проверить.
Отправка списка CA сертификатов полезна по нескольким причинам:
- Это позволяет клиенту заранее знать, какие сертификаты приемлемы для сервера, уменьшая вероятность неэффективной передачи сертификатов, которые не будут приняты.
- Если бы сервер не отправлял этот список, клиенту пришлось бы отправлять все свои сертификаты в надежде, что один из них будет принят, что действительно было бы неэффективно, особенно если у клиента много сертификатов.
Тем не менее, применение директивы ssl_trusted_certificate
позволяет указать файл с CA сертификатами, которые используются для проверки клиентских сертификатов, но они не отправляются клиенту в процессе рукопожатия TLS. Эта директива также используется для проверки ответов OCSP. Если вы хотите избежать отправки CA сертификатов клиенту, вам следует использовать именно ssl_trusted_certificate
.
Важно отметить, что на данный момент, если вы используете ssl_verify_client on;
, вам необходимо также указать директиву ssl_client_certificate
, поскольку Nginx требует наличия доверенного списка CA, который он отправляет клиенту. Это может выглядеть как противоречие, так как вы можете не желать отправлять сертификаты клиенту, но это необходимо для процесса верификации при текущей конфигурации.
С введением TLS 1.1+ не стало обязательным отправлять CA в запросе сертификата от сервера клиенту, и, следовательно, директива ssl_client_certificate
становится опциональной. Однако в Nginx, начиная с версии 1.28.0, планируется, что можно будет использовать только ssl_trusted_certificate
с включенной верификацией клиента. Это изменение упростит конфигурацию в случаях, когда отправка списка сертификатов не требуется.
Таким образом, если вы хотите использовать только ssl_trusted_certificate
, вам нужно удалить ssl_client_certificate
и убедиться, что конфигурация совместима с вашей версией Nginx и настроенными вами политиками безопасности.