Giter VIP home page Giter VIP logo

tlsauth's Introduction

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

./tlsauth.py root-ca createca http://localhost/crl.pem "Example CA" [email protected]

create a “client authentication CA” in ./sub-ca

./tlsauth.py sub-ca createca http://localhost/client-crl.pem "hostname client CA" [email protected] root-ca

create https server certificate

./tlsauth.py root-ca newcsr localhost root@localhost >server.key

Sign server cert with CA

./tlsauth.py sign <server.key >server.pem

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!)

mv root-ca/private/root.key <private and save location>

Setup nginx to serve

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") {
          uwsgi_pass 127.0.0.1:8080;
       }
       try_files $uri $uri/ /index.html;
    }
}

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.

webserver Demo

There’s a bundled demo, to try it out:

set up uwsgi

edit flask-demo/tlsdemo_wsgi.py

install python dependencies

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

run flask application

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

Client side setup

How to create a proper Client certificate.

Create a client certificate

./tlsauth.py root-ca newcsr joe joe@localhost >joe.key

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

./tlsauth.py root-ca sign <joe.key >joe.cert

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

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

./tlsauth.py root-ca p12 joe.key <joe.cert >joe.p12

This asks for a passphrase which is needed only once when importing into the browser.

Import the certificates in Firefox

  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

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

Changes

v0.4

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.