Welcome, guest | Sign In | My Account | Store | Cart

Notice! PyPM is being replaced with the ActiveState Platform, which enhances PyPM’s build and deploy capabilities. Create your free Platform account to download ActivePython or customize Python with the packages you require and get automatic updates.

Download
ActivePython
INSTALL>
pypm install tlsauth

How to install tlsauth

  1. Download and install ActivePython
  2. Open Command Prompt
  3. Type pypm install tlsauth
 Python 2.7Python 3.2Python 3.3
Windows (32-bit)
Windows (64-bit)
Mac OS X (10.5+)
Linux (32-bit)
Linux (64-bit)
0.4-1 Available View build log
 
License
BSD
Imports
Lastest release
version 0.4-1 on Jan 9th, 2014
  • tlsauth

This is a simple example how to setup TLS Certificate Authentication for your online services. The example is based on nginx and WSGI but should work also with an FCGI backend with PHP.

Using tlsauth you can authenticate your users based on certificates instead of passwords. In fact you don't have to store neither the usernames, their email addresses nor their nicks, it is all contained in the Client certificate that is stored and presented by the user. You can be sure, unless your signing key is compromised, noone else can create valid certificates but you. This eliminates the need to remember passwords and prohibits password bruteforcing. Using nginx, you can even display totally different content depending if an request is authenticated or not, routing unauthenticated users to static html for example while authenticated users having access to some dynamic content.

I don't want to scare you but this is essentially a self-signed CA, it provides all the neccessary basic tools to make this hassle-free. Your users only need to go through a registration procedure and then they could enjoy seamless single-sign-on to all your services, never being asked for a password again.

** CA and https service install *** create a "localhost CA" in ./root-ca

System Message: WARNING/2 (<string>, line 25); backlink

Inline strong start-string without end-string.

System Message: ERROR/3 (<string>, line 27)

Unexpected indentation.
#+BEGIN_SRC sh

System Message: WARNING/2 (<string>, line 28)

Block quote ends without a blank line; unexpected unindent.
./tlsauth.py root-ca createca http://localhost/crl.pem "Example CA" ca@example.com
#+END_SRC
*** create a "client authentication CA" in ./sub-ca

System Message: WARNING/2 (<string>, line 30); backlink

Inline strong start-string without end-string.

#+BEGIN_SRC sh

./tlsauth.py sub-ca createca http://localhost/client-crl.pem "hostname client CA" email@example.com root-ca
#+END_SRC
*** create https server certificate

System Message: WARNING/2 (<string>, line 34); backlink

Inline strong start-string without end-string.

#+BEGIN_SRC sh

./tlsauth.py root-ca newcsr localhost root@localhost >server.key
#+END_SRC
*** Sign server cert with CA

System Message: WARNING/2 (<string>, line 38); backlink

Inline strong start-string without end-string.

#+BEGIN_SRC sh

./tlsauth.py sign <server.key >server.pem
#+END_SRC

System Message: WARNING/2 (<string>, line 42)

Definition list ends without a blank line; unexpected unindent.

*** Remove Root CA private key It is important to remove and store the root CA private key in a safe offline location, as it can be used to mount a MITM attack against all users, who trust this key. You need this key in 1 year, when you need to renew your client CA certificate (per default it's only valid for one year!)

System Message: WARNING/2 (<string>, line 42); backlink

Inline strong start-string without end-string.

System Message: ERROR/3 (<string>, line 48)

Unexpected indentation.
#+BEGIN_SRC sh

System Message: WARNING/2 (<string>, line 49)

Block quote ends without a blank line; unexpected unindent.
mv root-ca/private/root.key <private and save location>
#+END_SRC
*** Setup nginx to serve

System Message: WARNING/2 (<string>, line 51); backlink

Inline strong start-string without end-string.

#+BEGIN_SRC sh

server {

listen 443; ssl on; server_name localhost;

ssl_certificate <pathto>/tlsauth/server.cert; ssl_certificate_key <pathto>/tlsauth/server.key; ssl_client_certificate <pathto>/tlsauth/sub-ca/public/root.pem; ssl_verify_client optional;

location / {

include uwsgi_params; uwsgi_param verified $ssl_client_verify; uwsgi_param dn $ssl_client_s_dn; if ( $ssl_client_verify = "SUCCESS") {

System Message: ERROR/3 (<string>, line 68)

Unexpected indentation.
uwsgi_pass 127.0.0.1:8080;

System Message: WARNING/2 (<string>, line 69)

Block quote ends without a blank line; unexpected unindent.

} try_files $uri $uri/ /index.html;

System Message: WARNING/2 (<string>, line 71)

Definition list ends without a blank line; unexpected unindent.

}

System Message: WARNING/2 (<string>, line 72)

Definition list ends without a blank line; unexpected unindent.

} #+END_SRC

System Message: ERROR/3 (<string>, line 74)

Unexpected indentation.

don't forget to restart nginx.

Now if users have a proper client cert installed the environment of the WSGI application will contain the variables 'verified' and 'dn' variables set accordingly.

System Message: WARNING/2 (<string>, line 79)

Block quote ends without a blank line; unexpected unindent.
** webserver Demo
There's a bundled demo, to try it out:
*** set up uwsgi

System Message: WARNING/2 (<string>, line 81); backlink

Inline strong start-string without end-string.

#+BEGIN_SRC sh

edit flask-demo/tlsdemo_wsgi.py
#+END_SRC
*** install python dependencies

System Message: WARNING/2 (<string>, line 85); backlink

Inline strong start-string without end-string.

#+BEGIN_SRC sh

System Message: WARNING/2 (<string>, line 87)

Definition list ends without a blank line; unexpected unindent.

virtualenv --distribute env source env/bin/activate pip install Flask uwsgi

System Message: ERROR/3 (<string>, line 90)

Unexpected indentation.
#+END_SRC

System Message: WARNING/2 (<string>, line 91)

Block quote ends without a blank line; unexpected unindent.
*** run flask application

System Message: WARNING/2 (<string>, line 91); backlink

Inline strong start-string without end-string.

#+BEGIN_SRC sh

System Message: WARNING/2 (<string>, line 93)

Definition list ends without a blank line; unexpected unindent.

basedir=$PWD env/bin/uwsgi --socket 127.0.0.1:8080 --chdir $basedir/flask-demo -pp $basedir -w tlsdemo_wsgi -p 1 --virtualenv $basedir/env

System Message: ERROR/3 (<string>, line 95)

Unexpected indentation.
#+END_SRC

System Message: WARNING/2 (<string>, line 96)

Block quote ends without a blank line; unexpected unindent.

** Client side setup How to create a proper Client certificate. *** Create a client certificate

System Message: WARNING/2 (<string>, line 96); backlink

Inline strong start-string without end-string.

System Message: ERROR/3 (<string>, line 99)

Unexpected indentation.
#+BEGIN_SRC sh

System Message: WARNING/2 (<string>, line 100)

Block quote ends without a blank line; unexpected unindent.
./tlsauth.py root-ca newcsr joe joe@localhost >joe.key

#+END_SRC send the resulting "user.csr" to the CA for signing. In this case you are both, but in a normal case this step is done by arbitrary users who send this csr file during the registration process to the site.

Store user.key away somewhere safe offline, you'll need it later once more.

*** CA signs users cert signing request

System Message: WARNING/2 (<string>, line 109); backlink

Inline strong start-string without end-string.

#+BEGIN_SRC sh

./tlsauth.py root-ca sign <joe.key >joe.cert
#+END_SRC CA sends back the signed 'user.cert" to the sender. As a convenience feature also the root CA cert should be sent to the user, so he can import this also in his CA store.
*** Create PKCS#12 cert for your browser

System Message: WARNING/2 (<string>, line 118); backlink

Inline strong start-string without end-string.

Using the returned cert from the CA we convert it together with the secret key part to a PKCS#12 #+BEGIN_SRC sh

./tlsauth.py root-ca p12 joe.key <joe.cert >joe.p12
#+END_SRC This asks for a passphrase which is needed only once when importing into the browser.
*** Import the certificates in Firefox

System Message: WARNING/2 (<string>, line 133); backlink

Inline strong start-string without end-string.
  1. Using the menu open the Preferences dialog.
  2. Select the Advanced toolbar icon
  3. click on the "View certificates" button
  4. On the "Authorities" tab click on the Import button and import the root CA cert (this must be supplied by the CA to you).
  5. on the "Your Certificates" tab click on the "Import" button and load the file "user.cert.p12"

if everything went ok the new certificate should appear under the "Your Certificates" tab

*** Securing keys

System Message: WARNING/2 (<string>, line 144); backlink

Inline strong start-string without end-string.

Store away private key in joe.key again together with the pkcs12 cert joe.p12 in a safe offline location (maybe your backup?), if you reinstall your browser you want to import user.cert.p12 back into it again.

If you now surf to https://localhost with this firefox, the flask application should report back your distinguished name. If you browse to this location with another browser which lacks this certificate you will probably see the default nginx installation html page.

** Python usage
see test.py

System Message: WARNING/2 (<string>, line 148)

Definition list ends without a blank line; unexpected unindent.

** Changes *** v0.4

System Message: WARNING/2 (<string>, line 148); backlink

Inline strong start-string without end-string.

System Message: ERROR/3 (<string>, line 150)

Unexpected indentation.
Fixed dangerously exposed Root CA key, by introducing a sub CA only for signing the client authentication keys, and thus eliminating the chance for a MITM attack in case the Root CA gets compromised.

Subscribe to package updates

Last updated Jan 9th, 2014

What does the lock icon mean?

Builds marked with a lock icon are only available via PyPM to users with a current ActivePython Business Edition subscription.

Need custom builds or support?

ActivePython Enterprise Edition guarantees priority access to technical support, indemnification, expert consulting and quality-assured language builds.

Plan on re-distributing ActivePython?

Get re-distribution rights and eliminate legal risks with ActivePython OEM Edition.