Perfect! Since you want ssl_verify_client on;, we need a CA to verify client certificates, because Nginx cannot accept client certs without knowing which CA signed them. Let’s set it up step by step.
Step 1: Create a CA
This will be the authority that signs your client certificates.
mkdir -p /etc/nginx/ssl
cd /etc/nginx/ssl
# Generate CA private key
openssl genrsa -out ca.key 4096
# Generate CA certificate
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.crt \
-subj "/C=US/ST=State/L=City/O=MyOrg/OU=IT/CN=MyRootCA"-
ca.crt→ used by Nginx asssl_client_certificate. -
ca.key→ keep secure, used to sign client certs.
Step 2: Generate a client certificate
This is what your clients will use to connect.
# Client private key
openssl genrsa -out client.key 2048
# Client CSR
openssl req -new -key client.key -out client.csr \
-subj "/C=US/ST=State/L=City/O=MyOrg/OU=IT/CN=client"
# Sign CSR with your CA
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-out client.crt -days 365 -sha256Now you have:
-
client.crt→ client certificate -
client.key→ client private key -
ca.crt→ CA certificate that Nginx will trust
Step 3: Update your Nginx config
server {
listen 443 ssl;
server_name remusic.servebeer.com;
ssl_certificate /etc/letsencrypt/live/remusic.servebeer.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/remusic.servebeer.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# 🔒 Client certificate verification
ssl_client_certificate /etc/nginx/ssl/ca.crt; # <--- CA you just created
ssl_verify_client on;
ssl_verify_depth 2; # optional
location / {
proxy_pass http://127.0.0.1:4533;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen 80;
server_name remusic.servebeer.com;
return 301 https://$host$request_uri;
}Step 4: Test your setup
sudo nginx -t
sudo systemctl reload nginxThen from a client machine:
curl -vk --cert client.crt --key client.key https://remusic.servebeer.com/-
✅ Works: if the client presents the valid certificate.
-
❌ Fails: if no certificate or an invalid one is provided.
Perfect! Let’s create a simple client certificate that you can use to test your Nginx setup with ssl_verify_client on. I’ll guide you step by step in a safe way, keeping the CA private key secure.
Step 1: Work in your home folder
We don’t need root for client files. On your server:
mkdir -p ~/ssl-client
cd ~/ssl-clientStep 2: Generate the client private key
openssl genrsa -out client.key 2048-
This is the client’s private key.
-
Keep this secret. Do not upload it to the server.
Step 3: Create a CSR (Certificate Signing Request)
openssl req -new -key client.key -out client.csr \
-subj "/C=IE/ST=PHB/L=DUB/O=Re/OU=IT/CN=client1"-
CN=client1→ identifies this client. -
The CSR is what the CA will sign to create the certificate.
Step 4: Sign the client certificate with your CA
Your CA files are in /etc/nginx/ssl/. Sign the CSR:
sudo openssl x509 -req -in client.csr -CA /etc/nginx/ssl/ca.crt -CAkey /etc/nginx/ssl/ca.key \
-CAcreateserial -out client.crt -days 365 -sha256✅ Now you have:
-
client.crt→ client certificate (can be given to the client) -
client.key→ client private key (client keeps this)
Note: Only the CA needs the private key (ca.key). You don’t share it.
Step 5: Test with curl
From the same machine or any client machine:
curl -vk --cert ~/ssl-client/client.crt --key ~/ssl-client/client.key https://remusic.servebeer.com/-
✅ Works if Nginx trusts the CA.
-
❌ Fails if no certificate or wrong certificate is used.
Step 6: Configure Nginx (if not already)
ssl_client_certificate /etc/nginx/ssl/ca.crt; # trust your CA
ssl_verify_client on; # require client cert
ssl_verify_depth 2;- Only clients with certificates signed by
ca.crtcan connect.
Back References: