I followed the instructions in this blog post, but when I test it with curl
, nginx's $ssl_client_verify
variable is always NONE
. In fact, curl
doesn't even give different output when I don't specify the --cert
and --key
options at all. It's as if it's ignoring my certs. How can I debug this?
I even tried making it so all of these places have the same value:
- The Common Name on the CA and Server certs
- The Server's hostname
- NginX's virtual host name
- The server's reverse DNS name
Best Answer
If by "Common Name" in CA and Server certs you mean the entire Subject name, which can contain other items besides Common Name although most people doing ad-hoc SSL certs like this don't bother with them, is the same -- don't do that. OpenSSL, which both nginx and curl use, cannot chain a child cert to a parent that has the same name; this is not a normal case in X.509 and may not be handled at least in general in other software either.
With that I believe it should work. A more basic and probably better test tool is openssl commandline:
which will output detailed information about the (attempted) SSL/TLS connection. If fairly near the end it says
Acceptable client certificate CA names
followed by the correct name of your CA, the server is setup correctly for client auth (as well as basic SSL). If it has some other name, or saysNo client certificate CA names sent
, something is wrong. Whens_client
waits for input just enter EOF (Unix usually ^D, Windows ^Z).Aside: the website is wrong to say signing the server request with your self-created ad-hoc CA key&cert is "self signing". Self-signing is specifically signing a cert with the same keypair whose public half is in that cert; in practice this is used only of a toplevel CA, called a "root". You are signing your server cert with your own CA, but you are not self-signing. Signing your server cert with your own CA is bad if you want to handle connections from strangers because it doesn't provide them any evidence to trust your server the way a "commercial" server cert from a well-known CA like Verisign or GoDaddy does. That is commonly the case for production as opposed to test, since test is often used only by developers and/or few beta testers, but some production systems can also be limited to few closely-related clients.
EDIT: getting ad-hoc CA (for client certs) signed by well-known CA: this would be difficult and expensive and is not necessary.
If a well-known CA gives you a "sub-CA" or "intermediate CA" cert allowing you to issue certs, they are betting the future of their business on your security -- so either you must provide security at the same level they do (custom hardware, specialized buildings, armed guards around the clock, multiple specially trained and certified personnel, regular external audits -- all expensive) or you have to buy out their business (so they are no longer at risk). In addition to your https://security.stackexchange.com/questions/25551/help-understanding-client-certificate-verification see:
But the only systems that need to trust the certs you issue your clients are your own servers; as long as you control your own servers you just configure them to trust your own CA cert.