title: Self-signed SSL connection using PyMongo
body: <p>I'm trying to create a secure SSL connection to MongoDB using PyMongo. The goal is to use this configuration for a Mongo instance running on EC2 to which I can connect with a Python client. For testing, I'm just trying to get the configuration working locally first. My as yet failing attempt can be found <a href="https://github.com/aisthesis/mongo-ssl" rel="noreferrer" title="here">here</a>.</p>
  
  <p>Short version of what I think is the problem: My client side certificate authority file <code>ca.pem</code> isn't correct. The way I have it, this file is actually identical to the one I'm using server side. Both were created using <code>x509</code> with <code>openssl</code>, and I suspect that my client side file needs some kind of different content, but I'm not sure exactly how to generate that content or if this suspicion is even correct.</p>
  
  <p>Here are the details of what I've done for creating the necessary certificates and keys (on Mac El Capitan):</p>
  
  <p>First, generate a certificate authority:</p>
  
  <pre><code>$ mkdir ~/ssl
  $ cd ~/ssl
  $ openssl req -out ca.pem -new -x509 -days 3650    
  # enter info
  </code></pre>
  
  <p>Generate server <code>.pem</code> file:</p>
  
  <pre><code>$ openssl genrsa -out server.key 2048
  $ openssl req -key server.key -new -out server.req
  # enter info
  $ openssl x509 -req -in server.req -CA ca.pem -CAkey privkey.pem -CAserial file.srl -out server.crt -days 3650
  $ cat server.key server.crt &gt; server.pem
  </code></pre>
  
  <p>Now do the same for the client:</p>
  
  <pre><code>$ openssl genrsa -out client.key 2048
  $ openssl req -key client.key -new -out client.req
  $ openssl x509 -req -in client.req -CA ca.pem -CAkey privkey.pem -CAserial file.srl -out client.crt -days 3650
  $ cat client.key client.crt &gt; client.pem
  </code></pre>
  
  <p>Then I do the following configurations in <code>etc/mongod.conf</code>:</p>
  
  <pre><code>net:
    ...
    ssl:
      mode: requireSSL
      PEMKeyFile: ~/ssl/server.pem
      CAFile: ~/ssl/ca.pem
  </code></pre>
  
  <p>Now starting mongo (Mac) with </p>
  
  <pre><code>$ mongod --config /etc/mongod.conf
  </code></pre>
  
  <p>works as expected. The process runs and seems to be accepting the configurations.</p>
  
  <p>Then on the Python side (also running on localhost for debugging), I do the following in calling mongo:</p>
  
  <pre><code>import ssl
  from pymongo import MongoClient
  
  client = MongoClient(
          '127.0.0.1',
          27017,
          ssl=True,
          ssl_certfile='~/ssl/client.pem',
          ssl_cert_reqs=ssl.CERT_REQUIRED,
          ssl_ca_certs='~/ssl/ca.pem'
          )
  # try a simple insert
  </code></pre>
  
  <p>When I run this, the Python code blocks after creating the <code>MongoClient</code>, and I see in the <code>mongo</code> logs:</p>
  
  <pre><code>2016-03-03T22:11:30.331-0800 E NETWORK  [conn21] SSL: error:14094418:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca
  </code></pre>
  
  <p>On the basis of Wan's comment below, I redid the whole thing, making sure that the information in the 'Distinguished Name' was consistent with those specifications. The old version definitely used the same Common Name for both server and client. The connection still isn't succeeding, but the messages are somewhat different:</p>
  
  <pre><code>2016-03-11T12:29:40.380-0800 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:57363 #3 (1 connection now open)
  2016-03-11T12:29:40.386-0800 I NETWORK  [conn3] end connection 127.0.0.1:57363 (0 connections now open)
  </code></pre>
  
  <p>These 2 messages just repeat until I stop the Python process, which blocks when attempting to open the connection. The <code>end connection</code> part is now in the place where the <code>alert unknown ca</code> line was previously in the mongo log.</p>
  
  <p>Additional info for debugging:</p>
  
  <pre><code>$ openssl verify -CAfile ca.pem client.pem
  client.pem: OK
  $ openssl verify -CAfile ca.pem server.pem
  server.pem: OK
  $ openssl x509 -noout -subject -in server.pem
  subject= /C=US/ST=Washington/L=Seattle/O=codeMelon/OU=Engineering/CN=server.com/emailAddress=&lt;my-email-address&gt;@gmail.com
  $ openssl x509 -noout -subject -in client.pem
  subject= /C=US/ST=Washington/L=Seattle/O=codeMelon/OU=Engineering/CN=client.com/emailAddress=&lt;my-email-address&gt;@gmail.com
  </code></pre>
  
  <p>The bottom line after getting the subject line properly formed is that mongo is accepting the connection, then ending it, and the Python process is blocking without ever making the intended insert.</p>
  
  <p>Any help is much appreciated!</p>