When implementing client SSL certificate authentication in Nginx, there are several critical components that must be properly configured:
server {
listen 443 ssl;
server_name service.domain.com;
ssl_certificate /etc/nginx/ssl/wildcard/server.crt;
ssl_certificate_key /etc/nginx/ssl/wildcard/server.key;
ssl_client_certificate /etc/nginx/ssl/client.certificates/client_package.cer;
ssl_verify_client on;
# Additional security settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
}
The error message "client sent no required SSL certificate" typically indicates one of several potential issues:
- The client isn't properly presenting its certificate
- The certificate chain is incomplete in your configuration
- The client certificate isn't properly trusted by your Nginx server
For proper verification, your ssl_client_certificate file should contain:
# Intermediate CA certificates (if any)
-----BEGIN CERTIFICATE-----
(intermediate CA 1)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
(intermediate CA 2)
-----END CERTIFICATE-----
# Root CA certificate
-----BEGIN CERTIFICATE-----
(root CA)
-----END CERTIFICATE-----
# All client certificates
-----BEGIN CERTIFICATE-----
(client cert 1)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
(client cert 2)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
(client cert 3)
-----END CERTIFICATE-----
To properly diagnose the issue, you can enable more detailed logging:
error_log /var/log/nginx/ssl_error.log debug;
ssl_verify_depth 3; # Ensure proper chain verification depth
ssl_crl /path/to/crl.pem; # If using Certificate Revocation Lists
You should also verify the certificates from the client side using OpenSSL:
openssl s_client -connect service.domain.com:443 -cert client_cert.pem -key client_key.pem -CAfile ca_bundle.crt
For more granular control, consider these additional parameters:
ssl_verify_client optional_no_ca; # For testing
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
Remember that different clients might handle certificate presentation differently, especially when intermediate CAs are involved.
When implementing client SSL certificate authentication in Nginx as a reverse proxy, several technical nuances can cause connection failures even when the configuration appears correct. The error message "client sent no required SSL certificate" often masks deeper configuration issues.
The essential Nginx directives for client certificate authentication:
server {
listen 443 ssl;
server_name service.domain.com;
# Server certificates
ssl_certificate /etc/nginx/ssl/wildcard/server.crt;
ssl_certificate_key /etc/nginx/ssl/wildcard/server.key;
# Client certificate configuration
ssl_client_certificate /etc/nginx/ssl/client.certificates/client_package.cer;
ssl_verify_client on;
# Recommended additional parameters
ssl_verify_depth 2;
ssl_protocols TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
}
Certificate Chain Validation
The client certificate bundle must include:
- All client certificates (public keys only)
- Intermediate CA certificates
- Root CA certificate (optional but recommended)
Example concatenation order:
# Correct bundle structure
cat client1.crt client2.crt client3.crt intermediate.crt root.crt > client_package.cer
Debugging Techniques
Enable detailed logging in Nginx:
error_log /var/log/nginx/error.log debug;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
Optional vs Mandatory Client Auth
For different security levels:
# Strict authentication
ssl_verify_client on;
# Optional authentication
ssl_verify_client optional;
ssl_verify_depth 2;
Passing Certificate Information
To proxy client certificate details to backend servers:
proxy_set_header X-SSL-Cert $ssl_client_cert;
proxy_set_header X-SSL-Verify $ssl_client_verify;
proxy_set_header X-SSL-Serial $ssl_client_serial;
Test client certificate authentication using OpenSSL:
openssl s_client -connect service.domain.com:443 \
-cert client.crt -key client.key -CAfile ca.crt
Check for proper certificate submission in the output:
Verify return code: 0 (ok)
Client Certificate
-----BEGIN CERTIFICATE-----
[... certificate content ...]
-----END CERTIFICATE-----