How to Properly Configure Nginx Client SSL Certificate Authentication for Multiple Client Machines


2 views

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:

  1. All client certificates (public keys only)
  2. Intermediate CA certificates
  3. 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-----