Skip to content

Instantly share code, notes, and snippets.

@olly
Last active November 28, 2021 16:26

Revisions

  1. olly renamed this gist Sep 22, 2015. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  2. olly created this gist Sep 22, 2015.
    21 changes: 21 additions & 0 deletions THOUGHTS.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,21 @@
    # Client SSL Authentication

    The use case I had when I implemented client SSL authentication was to secure a web interface for a centralised log service that I was running. I wanted it to have it available, securely, on the public internet. I implemented it using nginx's [ssl module](http://nginx.org/en/docs/http/ngx_http_ssl_module.html).

    I only had this available for 4-5 developers. I think I'd only attempt to use this for anyone who is comfortable with SSH keys or if it was an API client. I think the technical bar is a little too high for anything else.

    I wrote some scripts, which I've pushed to a public GitHub repository: [olly/heracles](https://github.com/olly/heracles). The README is a mix of actual commands that work, and thoughts for how things could be configured. The idea was for it to generate CAs, server certificates and client certificates, and store them in a git repository for easy backup. There in a fairly rough state, but what's there works and I had tested on a real setup.

    ## Authorization

    The setup I had, I didn't have a need for authorization (by that I mean identifying who users are). For my use case if you had a valid certificate you could have access. From my reading the general way to do pass on some of the information from the certificate (which are available to you as [embedded variables](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#variables) as HTTP headers to your service. You can then identify the user from the certificate.

    As far as I could tell there was no way to "sign" these values that were being passed to the proxy server, so you really have to trust that only your frontend server has access to the backend - otherwise spoofing is trivial.

    ## Revocation

    I also didn't deal with the revocation of certificates. There's a configuration option `ssl_crl` which allows you to specify a file of all the revoked certificates. I *think* you have to reload nginx to get it to re-read the file though. Maybe a fancy lua module with a lookup into a database is the way to go here though.

    ---

    Overall, I think the technical setup is fairly straight-forward. The hard bit, which I don't think anyone has truly solved, is the PKI management. I'm not sure what you're use case is, but if it's for secure access for API clients then take a look at [Vault](https://vaultproject.io) - I've only toyed around with it in development, but it looks very interesting. It has [PKI backend](https://vaultproject.io/docs/secrets/pki/index.html) which I think could be used for this.
    24 changes: 24 additions & 0 deletions nginx.conf
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,24 @@
    server {
    listen 443;
    ssl on;
    server_name logs.guardsman.io;

    ssl_certificate /etc/ssl/vault/server/hosts/logs.guardsman.io.crt;
    ssl_certificate_key /etc/ssl/vault/server/hosts/logs.guardsman.io.unlocked.key;
    ssl_client_certificate /etc/ssl/vault/ca.crt;
    ssl_verify_client on;

    location / {
    proxy_pass http://0.0.0.0:5601;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
    }

    error_page 400 /400.html;
    location /400.html {
    internal;
    }
    }