Por: @vilmarschm
Publicado em: 2018-09-14

Autenticação de usuário com certificado ssl

Com o avanço do  desenvolvimento dos produtos da Itflex, identificamos a necessidade de autentica usuário passando certificado ssl.

Estudo

O inclui os seguintes critérios de aceitação:

  • Estudo do funcionamento do Nginx com ssl
  • Estudo do openssl para gera certificado

Nginx

O Nginx é um servidor web e proxy reverso que inclui modulo ssl para aplicação que utiliza Https e além disso permite valida um certificado de cliente adicionado em seu navegador. Portanto permite autentica usuário sem passa a senha.

server {
    listen       443 ssl;
    server_name  teste.com.br;
    ssl_certificate      /etc/nginx/certs/server.crt;
    ssl_certificate_key  /etc/nginx/certs/server.key;
    ssl_client_certificate  /etc/nginx/certs/ca.crt;
    ssl_verify_client optional;

    access_log /var/log/nginx/teste.com.br;
    error_log /var/log/nginx/error.teste.com.br info;

    location / {
        proxy_pass          http://localhost:3000;
    }

    location = /auth-cert {
        if ($ssl_client_verify != SUCCESS) {
            return 403;
        }
        proxy_set_header SSL_CLIENT_SERIAL $ssl_client_serial;
        proxy_set_header SSL_CLIENT_S_DN $ssl_client_s_dn;
        proxy_pass          http://localhost:3000/api/auth/cert;
    }
}

Para habilida a validação de certificado do cliente é necessário definir o parâmetro ssl_verify_client, e seu valor pode ser:

  • on: sempre valida certificado do cliente
  • off: não valida certificado do cliente
  • optional: valida quando for passado o certificado

Para validação funcionar é necessário passa o certificado da CA, definido no parâmetro ssl_client_certificate.

Há variável **$ssl_client_verify, **contêm o resultado da validação do certificado. Permite desenvolver lógica para bloqueio ou redirecionamento da requisição. Que neste caso foi definido o retorno 403 Não Autorizado, quando o certificado não for válido.

O Nginx permite extrair algumas informações do certificado que serão utilizadas no tratamento da requisição:

  • $ssl_client_serial: Serial do certificado
  • $ssl_client_s_dn: Contém as informações do dono do certificado

Para gerar certificado para cliente

Foi utilizado o openssl, é necessário seguir o procedimento abaixo:  

  • Cria uma CA
openssl genrsa -des3 -out ca.key 4096
openssl req -new -x509 -days 365 -key ca.key -out ca.crt
  • Cria um certificado para cliente
openssl genrsa -des3 -out client.key 4096
openssl req -new -key client.key -out client.csr

# Sign the client certificate with our CA cert
openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt

Para validar se o certificado esta assiando corretamente, pode ser executado o comando

openssl verify -verbose -CAfile ca.crt client.crt
  • Converte o certificado de cliente para formato PKCS#12, formato que os navegadores aceitam
openssl pkcs12 -export -clcerts -inkey client.key -in client.crt -out client.p12 -name "MyKey"