SSL peer certificate validation failed:unsupported certificate purpose

3,810 views
Skip to first unread message

Micheal Shallop

unread,
Jan 26, 2016, 7:22:45 PM1/26/16
to mongodb-user
Trying to set-up SSL/TLS for a replication set.

Carefully generated and signed root, intermediate, and server certs.  All verified.  Server certs verified against the chain cert.  Chain cert verified against the root cert.

Took extra care in setting up the DNs for all the certs at all levels.  All nodes are defined in /etc/hosts and the node names match the CN in the server cert DNs.

Intermediate cert CN does not match the root cert CN.

The repl-set is solid - it connects and repls all day normally.  Until I add the SSL...

My mongod.conf ssl section:

    ssl:
        mode
:                       requireSSL
       
PEMKeyFile:                 /etc/ssl/mongo-prod1.pem
       
CAFile:                     /etc/ssl/ca-chain.cert.pem
       
PEMKeyPassword:             xxxxxxxxxxxxxxxx
        allowConnectionsWithoutCertificates
:  true

Where the mongo-prod[1-3].pem key files contain the server key + the server cert cat'd into a single file...


When I attempt to enable SSL/TLS is when things blow-up and throw exceptions, most of which are similar to:

Tue Jan 26 16:13:52.588 E NETWORK  [conn8070] SSL peer certificate validation failed:unsupported certificate purpose
Tue Jan 26 16:13:52.588 W -        [conn8070] DBException thrown :: caused by :: 9001 socket exception [CONNECT_ERROR] for
Tue Jan 26 16:13:52.593 I -        [conn8070]
 0xf82712 0xf03fbd 0x857bce 0xf42da1 0xf3b302 0xf31181 0xf33c40 0x7f5875e66182 0x7f587492d47d


When I built the server certs, I was very careful to specify the -extensions server_cert flag.  My cert validation dumps show:

        X509v3 extensions:
            X509v3
Basic Constraints:
                CA
:FALSE
           
Netscape Cert Type:
                SSL
Server
           
Netscape Comment:
               
OpenSSL Generated Server Certificate
            X509v3
Subject Key Identifier:
                F1
:85:92:F6:9E:6F:DD:F8:11:52:CA:FA:45:34:A3:A1:E6:EF:BC:E7
            X509v3
Authority Key Identifier:
                keyid
:A1:F5:E5:61:EE:CF:46:93:5A:2B:76:DA:E6:9E:DE:40:18:41:9F:25
               
DirName:/C=US/ST=California/O=PathwayGenomics
                serial
:10:01


            X509v3
Key Usage: critical
               
Digital Signature, Key Encipherment
            X509v3
Extended Key Usage:
                TLS
Web Server Authentication

output from rs.status():

ULPROD:SECONDARY> rs.status()
{
 
"set" : "ULPROD",
 
"date" : ISODate("2016-01-27T00:08:21.917Z"),
 
"myState" : 2,
 
"members" : [
 
{
 
"_id" : 0,
 
"name" : "mongo-prod1:27017",
 
"health" : 1,
 
"state" : 2,
 
"stateStr" : "SECONDARY",
 
"uptime" : 2400,
 
"optime" : Timestamp(1453333325, 28),
 
"optimeDate" : ISODate("2016-01-20T23:42:05Z"),
 
"configVersion" : 3,
 
"self" : true
 
},
 
{
 
"_id" : 1,
 
"name" : "mongo-prod2:27017",
 
"health" : 0,
 
"state" : 8,
 
"stateStr" : "(not reachable/healthy)",
 
"uptime" : 0,
 
"optime" : Timestamp(0, 0),
 
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
 
"lastHeartbeat" : ISODate("2016-01-27T00:08:19.749Z"),
 
"lastHeartbeatRecv" : ISODate("1970-01-01T00:00:00Z"),
 
"configVersion" : -1
 
},
 
{
 
"_id" : 2,
 
"name" : "mongo-prod3:27017",
 
"health" : 0,
 
"state" : 8,
 
"stateStr" : "(not reachable/healthy)",
 
"uptime" : 0,
 
"optime" : Timestamp(0, 0),
 
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
 
"lastHeartbeat" : ISODate("2016-01-27T00:08:19.923Z"),
 
"lastHeartbeatRecv" : ISODate("1970-01-01T00:00:00Z"),
 
"configVersion" : -1
 
}
 
],
 
"ok" : 1
}


My mongo client alias:

alias mongo='mongo --ssl --sslAllowInvalidHostnames --sslCAFile /etc/ssl/ca-chain.cert.pem --host mongo-prod1'



Thanks for listening... hope someone has encountered this before and can steer me to a better path.

--mike

Micheal Shallop

unread,
Mar 21, 2016, 3:56:46 PM3/21/16
to mongodb-user
Hey - for anyone else with similar issues, here's the solution...

When creating your certs, normally one would specify if the cert being generated as a server or a client certificate.  In order to get mongodb to work with SSL, you have to generate the (server and client) certs omitting the [ server | client ] parameter option.

For example:

openssl ca -config intermediate/openssl.cnf \
     
-extensions server_cert -days 375 -notext -md sha256 \
     
-in intermediate/csr/www.example.com.csr.pem \
     
-out intermediate/certs/www.example.com.cert.pem

Would be:

openssl ca -config intermediate/openssl.cnf \
     
-days 375 -notext -md sha256 \
     
-in intermediate/csr/www.example.com.csr.pem \
     
-out intermediate/certs/www.example.com.cert.pem

instead.

Hope this helps someone else....

--mike

Derek Gransaull

unread,
May 3, 2016, 2:35:22 AM5/3/16
to mongodb-user
This helped me. It's a pity the Mongo Docs are so sparse and, in this case, likely incorrect. I had tried with both clientAuth and serverAuth like the docs say, but that didn't work either. The only way it works is as you've said ... with no extensions. Thanks Micheal! 

Emilio Scalise

unread,
Sep 8, 2017, 8:55:22 AM9/8/17
to mongodb-user
Hi All,

If you set the SSL server extension for your server certificate, you can't use that certificate for client authentication and thus MongoDB can't use it to connect to the other replica set members. To specify a different client SSL certificate for the internal connections between the MongoDB replica set members or sharded cluster members you need to set the parameter "clusterFile" specifying a SSL PEM file with the client extension:

  ssl:
   
CAFile: /opt/ca-bundle.crt
   
PEMKeyFile: /opt/server.pem
   
PEMKeyPassword: password
    clusterFile
: /opt/client.pem
    clusterPassword
: password
    mode
: requireSSL


By default if "clusterFile" is not set it will be equal to "PEMKeyFile". This is why if you generate a SSL certificate without the "server" extension it will work.

I hope that this clarifies the issue discussed.

Kind regards,
Emilio
Reply all
Reply to author
Forward
0 new messages