If I am using a Apache to verify the client certificate and the client certificate is invalid (e.g. revoked) than I can get the appropriate SSL/TLS alert which can be evaluated by the client:
curl -v --insecure --cert cert.pem --key key.pem --cacert ca.pem https://127.0.0.1:443/1/config * Expire in 0 ms for 6 (transfer 0x5611097bcfb0) * Trying 127.0.0.1... * TCP_NODELAY set * Expire in 200 ms for 4 (transfer 0x5611097bcfb0) * Connected to 127.0.0.1 (127.0.0.1) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: ca.pem CApath: /etc/ssl/certs * TLSv1.3 (OUT), TLS handshake, Client hello (1): * TLSv1.3 (IN), TLS handshake, Server hello (2): * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8): * TLSv1.3 (IN), TLS handshake, Request CERT (13): * TLSv1.3 (IN), TLS handshake, Certificate (11): * TLSv1.3 (IN), TLS handshake, CERT verify (15): * TLSv1.3 (IN), TLS handshake, Finished (20): * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.3 (OUT), TLS handshake, Certificate (11): * TLSv1.3 (OUT), TLS handshake, CERT verify (15): * TLSv1.3 (OUT), TLS handshake, Finished (20): * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 * ALPN, server accepted to use http/1.1 * Server certificate: * subject: C=ZZ; ST=YY; L=Duckburg; O=McDuck LLC.; OU=moneybin; CN=moneybin.example.com * start date: Jan 1 01:02:03 2021 UTC * expire date: Jan 1 01:02:03 2022 UTC * issuer: C=ZZ; ST=YY; L=Duckburg; O=McDuck LLC.; CN=Scrooge CA * SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway. > GET /1/config HTTP/1.1 > Host: 127.0.0.1 > User-Agent: curl/7.64.0 > Accept: */* > * TLSv1.3 (IN), TLS alert, certificate revoked (556): * OpenSSL SSL_read: error:14094414:SSL routines:ssl3_read_bytes:sslv3 alert certificate revoked, errno 0 * Closing connection 0 curl: (56) OpenSSL SSL_read: error:14094414:SSL routines:ssl3_read_bytes:sslv3 alert certificate revoked, errno 0 This is awesome because the (API) client can evaluate this information and start the correct actions based on that information. But for ningx (with the default configuration), I only get a generic error when the SSL certificate is revoked: curl -v --insecure --cert cert.pem --key key.pem --cacert ca.pem https://127.0.0.1:443/1/config * Expire in 0 ms for 6 (transfer 0x5611097bcfb0) * Trying 127.0.0.1... * TCP_NODELAY set * Expire in 200 ms for 4 (transfer 0x5611097bcfb0) * Connected to 127.0.0.1 (127.0.0.1) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: ca.pem CApath: /etc/ssl/certs * TLSv1.3 (OUT), TLS handshake, Client hello (1): * TLSv1.3 (IN), TLS handshake, Server hello (2): * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8): * TLSv1.3 (IN), TLS handshake, Request CERT (13): * TLSv1.3 (IN), TLS handshake, Certificate (11): * TLSv1.3 (IN), TLS handshake, CERT verify (15): * TLSv1.3 (IN), TLS handshake, Finished (20): * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.3 (OUT), TLS handshake, Certificate (11): * TLSv1.3 (OUT), TLS handshake, CERT verify (15): * TLSv1.3 (OUT), TLS handshake, Finished (20): * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 * ALPN, server accepted to use h2 * Server certificate: * subject: C=ZZ; ST=YY; L=Duckburg; O=McDuck LLC.; OU=moneybin; CN=moneybin.example.com * start date: Jan 1 01:02:03 2021 UTC * expire date: Jan 1 01:02:03 2022 UTC * issuer: C=ZZ; ST=YY; L=Duckburg; O=McDuck LLC.; CN=Scrooge CA * SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway. * Using HTTP2, server supports multi-use * Connection state changed (HTTP/2 confirmed) * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0 * Using Stream ID: 1 (easy handle 0x5611097bcfb0) > GET /1/config HTTP/2 > Host: 127.0.0.1:443 > User-Agent: curl/7.64.0 > Accept: */* > * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): * old SSL session ID is stale, removing * Connection state changed (MAX_CONCURRENT_STREAMS == 128)! < HTTP/2 400 < server: nginx < date: Tue, 02 Mar 2021 07:54:36 GMT < content-type: text/html < content-length: 224 < strict-transport-security: max-age=63072000; includeSubDomains; preload < <html> <head><title>400 The SSL certificate error</title></head> <body bgcolor="white"> <center><h1>400 Bad Request</h1></center> <center>The SSL certificate error</center> <hr><center>nginx</center> </body> </html> * Connection #0 to host 127.0.0.1 left intact How can I force nginx also to report the client certificate error via the TLS alert mechanisms instead of this useless HTML page? --- Here is the nginx site configuration as reference: server { listen 443 ssl http2 default_server; error_log /var/log/nginx/moneybin_error.log; access_log /var/log/nginx/moneybin_access.log; ssl_certificate /some/path/to/certs/fullchain.pem; ssl_certificate_key /some/path/to/certs/privkey.pem; ssl_client_certificate /some/path/to/certs/ca.pem; ssl_trusted_certificate /some/path/to/certs/ca.pem; ssl_crl /some/path/to/certs/crl.pem; ssl_session_timeout 1d; ssl_session_cache off; ssl_session_tickets off; # intermediate configuration ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off; ssl_verify_client optional; ssl_verify_depth 2; root /var/www/moneybin; server_name _; location / { fastcgi_param HTTP_PROXY ""; fastcgi_pass unix:/var/run/php/php7.3-fpm.sock; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME /var/www/moneybin/index.php; } } Posted at Nginx Forum: https://forum.nginx.org/read.php?2,290872,290872#msg-290872 _______________________________________________ nginx mailing list nginx@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx