11

OK, I am trying to use client certificates to authenticate a python client to an Nginx server. Here is what I tried so far:

Created a local CA

openssl genrsa -des3 -out ca.key 4096
openssl req -new -x509 -days 365 -key ca.key -out ca.crt

Created server key and certificate

openssl genrsa -des3 -out server.key 1024
openssl rsa -in server.key -out server.key
openssl req -new -key server.key -out server.csr
openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt

Used similar procedure to create a client key and certificate

openssl genrsa -des3 -out client.key 1024
openssl rsa -in client.key -out client.key
openssl req -new -key client.key -out client.csr
openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt

Add these lines to my nginx config

server {
    listen 443;
    ssl on;
    server_name dev.lightcloud.com;
    keepalive_timeout 70;

    access_log /usr/local/var/log/nginx/lightcloud.access.log;
    error_log /usr/local/var/log/nginx/lightcloud.error.log;

    ssl_certificate /Users/wombat/Lightcloud-Web/ssl/server.crt;
    ssl_certificate_key /Users/wombat/Lightcloud-Web/ssl/server.key;
    ssl_client_certificate /Users/wombat/Lightcloud-Web/ssl/ca.crt;
    ssl_verify_client on;

    location / {
        uwsgi_pass unix:///tmp/uwsgi.socket;
        include uwsgi_params;
    }
}

created a PEM client file

cat client.crt client.key ca.crt > client.pem

created a test python script

import ssl
import http.client

context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
context.load_verify_locations("ca.crt")
context.load_cert_chain("client.pem")

conn = http.client.HTTPSConnection("localhost", context=context)
conn.set_debuglevel(3)

conn.putrequest('GET', '/')
conn.endheaders()
response = conn.getresponse()
print(response.read())

And now I get 400 The SSL certificate error from the server. What am I doing wrong?

1
  • It looks like my problem might be self-signed certificate. Looks like the only options for client verification that nginx supports is either full-on which fails on self-signed and optional_no_ca that allows clients in even if no certificate is presented. Is there a way to make nginx require a valid client certificate without checking for trusted CA? Or make it trust my local CA? Commented Nov 3, 2015 at 16:59

1 Answer 1

9

It seems that my problem was that I did not create the CA properly and wasn't signing keys the right way. A CA cert needs to be signed and if you pretend to be top level CA you self-sign your CA cert.

openssl req -new -newkey rsa:2048 -keyout ca.key -out ca.pem
openssl ca -create_serial -out cacert.pem -days 365 -keyfile ca.key -selfsign -infiles ca.pem

Then you use ca command to sign requests

openssl genrsa -des3 -out server.key 1024
openssl req -new -key server.key -out server.csr
openssl ca -out server.pem -infiles server.csr 
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.