SSL client certificate login pt.3

February 25th, 2008

Well, I made it, kinda…

The code is still a awful mess, but it works. Some portions of the code and setup are dictated by my setup involving a nginx server. With apache it should be simpler, with lighttpd it wouldn’t work at all, as far as I know.

Anyway, this is the way it works. You go to the site with http and register. The modified restful_authentication plugin instantly generates your client certificate. You get by clicking a link in the p12 format. The signing (self-signed) certificate is generated with the first user certificate (i’ll move this to a rake task later). After installing the certificate you can go to the site with https (before installing it nginx would reject you and redirect you to the non-https version of the login page). Now, if you log out and go to the session/new page, your certificate gets checked and, if your user is found (he should be), you get logged in automagically. Not much, but it’s all it does.

Now, about the code. There is not much code, really. Everything works from a combination of the modded restful_authentication plugin and the QuickCert library. If someone will actually find the whole thing useful, i’ll repackage it as a restful_authentication plugin fork, with some rake tasks and generators, and stuff. The nginx server is configured to use a self-signed certificate for the SSL connection, and the app generated certificate to check client certificates, this way:
server {
    listen       443;
    server_name  ssltest.startika.com;
    ssl                  on;
    ssl_certificate      /u/stuff/CA/demoCA/private/server.crt;
    ssl_certificate_key  /u/stuff/CA/demoCA/private/server.key;
    ssl_client_certificate /u/apps/ssltest/current/cert/CA/cacert.pem;
    ssl_verify_client on;
    ssl_verify_depth 2;
    ssl_session_timeout  5m;
    error_page 496 http://ssltest.startika.com/session/new;
    error_page 495 http://ssltest.startika.com/session/new;
    error_page 497 http://ssltest.startika.com/session/new;
    ssl_protocols  SSLv2 SSLv3 TLSv1;
    ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
    ssl_prefer_server_ciphers   on;
    root   /u/apps/ssltest/current;
    location / {
      proxy_set_header X-Real-IP  $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_set_header X-FORWARDED_PROTO https;
      proxy_set_header X-SSL_CLIENT_S_DN $ssl_client_s_dn;
      proxy_set_header X-SSL_PROTO $ssl_protocol;
      proxy_pass http://ssl_test;
      break;
  }
}

Well, if you want to see for yourself, just go to http://ssltest.startika.com/.

If you want to see the code (I’m ashamed of it, but it’s the only proof I have I actually made this), you can get it from github here: http://github.com/labria/rails-ssl-authentication/ (sorry for the mess, I’m quite a noob programmer yet…)

PS: If you will actually go and test the thing, don’t forget Safari has serious issues with certificates, better use Firefox =)

2 Responses to “SSL client certificate login pt.3”

  1. Dr Nic Says:
    Nice work. Opening the certificate from firefox loaded it into my keychain, so I needed to manually import it into Firefox. Then I logged out + I went to the /sesssions/new page and it took me to the https://ssltest.startika.com/test/ page, so it must be working (though I final "you've logged in!!" page might be nice :)
  2. labria Says:
    Yeah, i really should add some message to show it's really working =)

Leave a Reply