I am trying to secure a rethinkdb cluster behind stunnel. The service needs to support multiple Certificate Authorities (CA). Currently I concat the accepted CAs into one file (/certs/ca.pem) but it seems stunnel will only accept connections that match the first certificate in the file.
My stunnel configuration:
foreground = yes
sslVersion = TLSv1.2
options = NO_SSLv2
options = NO_SSLv3
[driver]
client = no
accept = 28415
connect = 127.0.0.1:28015
cert = /certs/server.pem
key = /certs/server-key.pem
CAfile = /certs/ca.pem
verify = 2
Stunnel version 5.06
Stunnel's log:
2016.02.18 22:18:51 LOG5[18]: Service [driver] accepted connection from 209.136.228.130:58728
2016.02.18 22:18:51 LOG4[18]: CERT: Verification error: self signed certificate
2016.02.18 22:18:51 LOG4[18]: Rejected by CERT at depth=0: C=US, OU=Edit LLC, L=Fresno, O=Edit LLC, ST=CA, CN=jason-Lemur-Ultra
2016.02.18 22:18:51 LOG3[18]: SSL_accept: 140890B2: error:140890B2:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:no certificate returned
2016.02.18 22:18:51 LOG5[18]: Connection reset: 0 byte(s) sent to SSL, 0 byte(s) sent to socket
And on the client side I get the following error:
SSL handshake failed: [SSL: TLSV1_ALERT_UNKNOWN_CA] tlsv1 alert unknown ca (_ssl.c:590)
I am not sure why stunnel says no certificate returned.
Edit: The error is coming from openssl. Here is how I can reproduce:
$ cat ca.cert.pem incomming-ca.pem > bigca.pem
$ openssl verify -CAfile bigca.pem incomming-ca.pem
incomming-ca.pem: C = US, OU = Edit LLC, L = Fresno, O = Edit LLC, ST = CA, CN = jason-Lemur-Ultra
error 18 at 0 depth lookup:self signed certificate
OK
$ openssl verify -CAfile bigca.pem ca.cert.pem
ca.cert.pem: OK
$ cat incomming-ca.pem ca.cert.pem > bigca.pem
$ openssl verify -CAfile bigca.pem incomming-ca.pem
incomming-ca.pem: OK
Edit(2): Here I try to verify a signed certificate instead of sending a root CA
$ openssl genrsa -des3 -out server.key 1024
$ openssl req -new -key server.key -out server.csr
$ openssl x509 -req -days 360 -in server.csr -CA ca.cert.pem -CAkey ca.key.pem -CAcreateserial -out server.crt
$ cat ca.cert.pem incomming-ca.pem > bigca.pem
$ openssl verify -CAfile bigca.pem server.crt
server.crt: OK
Cool, but lets switch the order of bigca.pem
$ cat incomming-ca.pem ca.cert.pem > bigca.pem
$ openssl verify -CAfile bigca.pem server.crt
server.crt: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd
error 7 at 0 depth lookup:certificate signature failure
140351186847392:error:0407006A:rsa routines:RSA_padding_check_PKCS1_type_1:block type is not 01:rsa_pk1.c:100:
140351186847392:error:04067072:rsa routines:RSA_EAY_PUBLIC_DECRYPT:padding check failed:rsa_eay.c:721:
140351186847392:error:0D0C5006:asn1 encoding routines:ASN1_item_verify:EVP lib:a_verify.c:233:
Best Answer
By configuring
stunnel
to require client certificates, using:You are telling
stunnel
to drop/refuse any clients who do not provide a valid client certificate. And this log message indicates that the client didn't provide a client certificate, and is thus rejected:This we know. Now, for why this happens. That client-side message is our hint:
A TLS server requests that the client send its client certificate by sending a list of trusted CAs; these are the CA certificates that are in your
/certs/ca.pem
file. The client, then, looks for a certificate that comes from one of those CAs; if the client does not have a certificate at all, or does not have a certificate which comes from one of those CAs, then the client will not provide a certificate at all.The fact that your client is saying that it does not recognize any of the CAs sent by the server says that your client either a) doesn't have a client certificate, or b) its client certificate is from a CA that is not in the
/certs/ca.pem
file.I am not sure which TLS client you are using, so I cannot help with that, but the above suggests that you check the configuration of the client certificate/key for that client, and check that the certificate configured for use by the client is from one of the CAs in your
/certs/ca.pem
file.Hope this helps!