Package: tlsauth
* tlsauthThis is a simple example how to setup TLS Certificate Authenticationfor your online services. The example is based on nginx and WSGI butshould work also with an FCGI backend with PHP.Using tlsauth you can authenticate your users based on certificatesinstead of passwords. In fact you don't have to store neither theusernames, their email addresses nor their nicks, it is all containedin the Client certificate that is stored and presented by theuser. You can be sure, unless your signing key is compromised, nooneelse can create valid certificates but you. This eliminates the needto remember passwords and prohibits password bruteforcing. Usingnginx, you can even display totally different content depending if anrequest is authenticated or not, routing unauthenticated users tostatic html for example while authenticated users having access tosome dynamic content.I don't want to scare you but this is essentially a self-signed CA, itprovides all the neccessary basic tools to make this hassle-free. Yourusers only need to go through a registration procedure and then theycould enjoy seamless single-sign-on to all your services, never beingasked for a password again.** CA and https service install*** create a "localhost CA" in ./root-ca#+BEGIN_SRC sh./tlsauth.py root-ca createca http://localhost/crl.pem "Example CA" ca@example.com#+END_SRC*** create a "client authentication CA" in ./sub-ca#+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#+BEGIN_SRC sh./tlsauth.py root-ca newcsr localhost root@localhost >server.key#+END_SRC*** Sign server cert with CA#+BEGIN_SRC sh./tlsauth.py sign <server.key >server.pem#+END_SRC*** Remove Root CA private keyIt is important to remove and store the root CA private key in a safeoffline location, as it can be used to mount a MITM attack against allusers, who trust this key. You need this key in 1 year, when you needto renew your client CA certificate (per default it's only valid forone year!)#+BEGIN_SRC shmv root-ca/private/root.key <private and save location>#+END_SRC*** Setup nginx to serve#+BEGIN_SRC shserver {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") {uwsgi_pass 127.0.0.1:8080;}try_files $uri $uri/ /index.html;}}#+END_SRCdon't forget to restart nginx.Now if users have a proper client cert installed the environment ofthe WSGI application will contain the variables 'verified' and 'dn'variables set accordingly.** webserver DemoThere's a bundled demo, to try it out:*** set up uwsgi#+BEGIN_SRC shedit flask-demo/tlsdemo_wsgi.py#+END_SRC*** install python dependencies#+BEGIN_SRC shvirtualenv --distribute envsource env/bin/activatepip install Flask uwsgi#+END_SRC*** run flask application#+BEGIN_SRC shbasedir=$PWDenv/bin/uwsgi --socket 127.0.0.1:8080 --chdir $basedir/flask-demo -pp $basedir -w tlsdemo_wsgi -p 1 --virtualenv $basedir/env#+END_SRC** Client side setupHow to create a proper Client certificate.*** Create a client certificate#+BEGIN_SRC sh./tlsauth.py root-ca newcsr joe joe@localhost >joe.key#+END_SRCsend the resulting "user.csr" to the CA for signing. In this caseyou are both, but in a normal case this step is done by arbitraryusers who send this csr file during the registration process to thesite.Store user.key away somewhere safe offline, you'll need it lateronce more.*** CA signs users cert signing request#+BEGIN_SRC sh./tlsauth.py root-ca sign <joe.key >joe.cert#+END_SRCCA sends back the signed 'user.cert" to the sender. As aconvenience feature also the root CA cert should be sent to theuser, so he can import this also in his CA store.*** Create PKCS#12 cert for your browserUsing the returned cert from the CA we convert it together with thesecret key part to a PKCS#12#+BEGIN_SRC sh./tlsauth.py root-ca p12 joe.key <joe.cert >joe.p12#+END_SRCThis asks for a passphrase which is needed only once when importinginto the browser.*** Import the certificates in Firefox1. Using the menu open the Preferences dialog.2. Select the Advanced toolbar icon3. click on the "View certificates" button4. On the "Authorities" tab click on the Import button and importthe root CA cert (this must be supplied by the CA to you).5. on the "Your Certificates" tab click on the "Import" button andload the file "user.cert.p12"if everything went ok the new certificate should appear under the"Your Certificates" tab*** Securing keysStore away private key in joe.key again together with the pkcs12cert joe.p12 in a safe offline location (maybe your backup?), ifyou reinstall your browser you want to import user.cert.p12 backinto it again.If you now surf to https://localhost with this firefox, the flaskapplication should report back your distinguished name. If youbrowse to this location with another browser which lacks thiscertificate you will probably see the default nginx installationhtml page.** Python usagesee test.py** Changes*** v0.4Fixed dangerously exposed Root CA key, by introducing a sub CAonly for signing the client authentication keys, and thuseliminating the chance for a MITM attack in case the Root CA getscompromised.