Message d’erreur
400 No required SSL certificate was sent
Également affiché sous la forme
- client sent no required SSL certificate while reading client request headers
Le titre de la page est « 400 No required SSL certificate was sent » ; avec un certificat dont la vérification échoue, nginx affiche plutôt « 400 The SSL certificate error ». La ligne de journal est écrite au niveau info : elle est donc invisible avec le niveau par défaut d’error_log.
nginx — ssl_verify_client on, request without a client certificate
Ce que cela signifie
nginx est configuré pour le TLS mutuel (ssl_verify_client on) et la requête est arrivée sur une connexion TLS au cours de laquelle le client n’a présenté aucun certificat. Au lieu de faire échouer le handshake, nginx le mène à terme et répond à chaque requête par cette page HTTP 400, en journalisant « client sent no required SSL certificate » au niveau info. La correction se fait côté client : celui-ci doit présenter un certificat émis par l’AC indiquée dans ssl_client_certificate.
Pourquoi cela se produit
Le client n’a pas envoyé de certificat
fréquentecurl, des scripts et des clients d’API sans --cert/--key ni l’option équivalente de leur bibliothèque ; des conteneurs ou des jobs de CI auxquels manque le secret qui contient le certificat.
Le navigateur n’avait aucun certificat correspondant
fréquenteLes navigateurs ne proposent que des certificats émis par une AC annoncée par nginx (tirée de ssl_client_certificate) ; avec un certificat d’une autre AC, ou sans aucun certificat importé, le navigateur n’envoie rien.
Un proxy termine la connexion TLS avant nginx
occasionnelleUn CDN, un répartiteur de charge ou un autre nginx placé devant ouvre sa propre connexion TLS sans certificat client ; le TLS mutuel doit alors être configuré sur ce saut (ou assuré en périphérie).
Comment corriger l’erreur
- 1.
Présenter le certificat client
Fournissez le certificat et la clé au client ; pour les navigateurs et les magasins de clés Windows/macOS, regroupez-les dans un fichier PKCS#12 et importez ce fichier.
bash curl --cert client.pem --key client.key https://mtls.example.com/ # Browsers: import the client certificate with its key as PKCS#12 openssl pkcs12 -export -in client.pem -inkey client.key -out client.p12 - 2.
Proxy vers un service mTLS : configurer le certificat amont
Lorsque nginx est lui-même le client du service mTLS, proxy_ssl_certificate et proxy_ssl_certificate_key fournissent le certificat sur la connexion amont.
text # nginx proxying to an mTLS upstream: present the client certificate on the upstream connection location / { proxy_pass https://mtls.example.com; proxy_ssl_certificate /etc/nginx/tls/client.pem; proxy_ssl_certificate_key /etc/nginx/tls/client.key; proxy_ssl_server_name on; } - 3.
N’exiger les certificats que là où c’est nécessaire
ssl_verify_client optional, associé à un contrôle de $ssl_client_verify dans chaque bloc location, laisse les contrôles d’intégrité et les chemins publics accessibles sans certificat.
text # Require the certificate only where needed ssl_verify_client optional; location /api/ { if ($ssl_client_verify != SUCCESS) { return 403; } }