UP | HOME

LPI-2 202-450 Topico 208.2
Configuração do HTTPS no Apache

Índice

208.2 Configuração do Apache para HTTPS - Objetivos

Peso 3

O Candidato deve ser capaz de configurar um servidor web para HTTPS. Conhecimentos-chave:

  • Arquivos de configuração e ferramentas do SSL;
  • Capacidade de gerar uma chave privada de servidor e um CSR para um CA comercial;
  • Capacidade de gerar um Certificado auto-assinado de um CA privado;
  • Capacidade de instalar a chave e o certificado;
  • Configuração de Hosts Virtuais com SNI;
  • Noção das questões sobre Hosts Virtuais e o uso de SSL;
  • Questões de segurança no uso de SSL.

Lista parcial dos arquivos, termos e ferramentas utilizadas:

  • Arquivos de configuração do Apache2;
  • /etc/ssl/*, /etc/pki/*;
  • openssl, CA.pl;
  • SSLEngine, SSLCertificateKeyFile, SSLCertificatePath;
  • SSLCACertificateFile, SSLCACertificatePath;
  • SSLProtocol, SSLCipherSuite, ServerTokens, ServerSignature, TraceEnable.

208.2 Configuração do Apache para HTTPS - Conteúdo

Criptografia

Entende-se por "texto plano" qualquer tipo de dado que possa ser "lido" no computador. Pode ser um arquivo, uma imagem, até mesmo um texto em .txt. Em uma interação criptografada esse arquivo em "texto plano" é tratado por um processo de criptografia usando uma hash conhecida como "chave de criptografia" e após isso temos o mesmo arquivo porém cifrado.

O texto após cifrado pode ser enviado por um meio público como a Internet para alguém sem risco de que se ele possa ser "lido" caso for "capturado" por um terceiro.

Após o arquivo recebido pelo devido destinatário, esse de posse da "chave de descritografia" consegue executar o processo inverso ao da criptografia, descifrando o arquivo para poder lê-lo.

Criptografia simétrica

A criptografia simétrica é o processo onde a chave de criptografia e a chave de descriptografia são idênticas (chave compartilhada).

Sorry, your browser does not support SVG.

Figura 1: Processo de criptografia simetrica

Nesse formato toda a segurança do processo é baseado nessa "chave compartilhada" e caso algum terceiro obtiver o acesso à essa chave a segurança da operação fica comprometida.

Criptografia assimétrica

Na criptografia assimétrica ao invés de gerarmos uma chave compartilhada geramos um par de chaves. Uma é a chave pública que é usada para criptografar os dados e a outra é a chave privada que é a usada para descriptografar os dados.

Sorry, your browser does not support SVG.

Figura 2: Processo de criptografia assimétrica

Hash

O processo de hash é uma transformação de "via de mão única". Tem as seguintes características.

  • A entrada pode ter tamanho variável, mas a saída terá sempre um tamanho fixo;
  • Não pode ser revertida ao estado original.

Sorry, your browser does not support SVG.

Figura 3: Fluxo de caminho único da hash

Assinaturas digitais

A combinação de chaves públicas e privadas com hashes cria assinaturas digitais. Essas assinaturas digitais nos dão grande confiança de que o arquivo que recebemos realmente veio da pessoa de quem pensamos ser, e não foi modificado por acidente ou maliciosamente, desde que foi assinado.

Sorry, your browser does not support SVG.

Figura 4: Verificação de assinatura

Uma coisa a notar sobre tudo isso, é que estamos supondo aqui, que a chave pública que obtivemos realmente é a chave pública do criador que originou o documento com a assinatura que estamos tentando verificar.

Secure Socket Layer (SSL)

Assinaturas digitais são usadas em SSL, que é uma camada na pilha de protocolos, assenta acima da camada de transporte e verifica a identidade do servidor e negocia a chave de sessão assimétrica que será usada para criptografar todo o tráfego entre o navegador e o servidor.

ssl-diagram.png

Figura 5: Fluxo SSL

Neste diagrama, o navegador e o servidor se comunicam primeiro por meio da pilha de protocolos TCP/IP normal e essa comunicação não é criptografada (caminho inseguro).

SSL é uma camada acima da camada de transporte na extremidade do cliente e do servidor e o hand shake é realizado quando a conexão SSL é feita, verifica a identidade do servidor e negocia a chave de sessão assimétrica que nos dá um caminho seguro entre o navegador e o servidor.

SSL depende do uso de Certificados Digitais. E, basicamente, um Certificado Digital é uma coleção de informações que identificam um site, assinada por alguma autoridade de certificação de terceiros confiável. Os certificados digitais contêm:

  • A identidade do emissor - Autoridade Certificadora (CA);
  • O nome de domínio e a chave pública do site;
  • Data de validade;
  • A assinatura da CA.

Sorry, your browser does not support SVG.

Figura 6: Estrutura de um certificado

Gerando um certificado

O OpenSSL é um toolkit open-source contendo ferramentas de linha de comando (CLI) e também bibliotecas que suportam várias operações criptográficas relacionadas ao SSL.

O processo de gerar um certificado se inicia com a geração de uma chave privada que é feita com o uso do comando openssl.

O próprio comando openssl pode ser usado para:

  • Criar e gerenciar chaves públicas e privadas;
  • A criação de certificados X509 e também solicitações de certificados (CRS);
  • Cálculo de hashes;
  • Criptografia e descriptografia.

O processo para obter um certificado começa com a criação de uma chave privada com o comando openssl na seguinte sintaxe:

openssl genrsa -des3 -out www.exemplo.com.br.key 1024

Assim criaremos uma chave privada usando criptografia Triple DES que terá o nome "www.exemplo.com.br.key". Durante o processo de criação da chave privada será solicitada a criação de uma senha. Esta senha é importante ser anotada.

Também é possível criar uma chave privada sem necessidade de senha, apesar de ser um processo menos seguro ele acaba sendo útil em alguns cenários:

openssl genrsa -out www.exemplo.com.br.key 1024

Após a criação da chave privada criaremos a Certificate Signing Request (CSR) ou Requisição de Assinatura de Certificado. O CSR é um pacote de informações contendo uma chave pública e informações relativas ao site a publicar (Cidade, País, Email, Organização, etc…) atenção ao item Common Name este deve ser preenchido com o endereço do site (sem o http://).

openssl req -new -key www.exemplo.com.br.key -out www.exemplo.com.br.csr

O arquivo resultante "www.exemplo.com.br.csr" deverá ser enviado para a CA.

A CA de posse do CSR utilizará a chave pública dela para calcular em conjunto com a chave pública constante no certificado e os dados fornecidos para gerar o certificado digital que será entregue ao solicitante.

Sorry, your browser does not support SVG.

Figura 7: Fluxo de geração de um certificado

O formato PKCS # 12

Trata-se de um formato binário usado para armazenar todos os elementos da cadeia de confiança, como o certificado do servidor, quaisquer certificados intermediários e a chave privada em um único arquivo criptografável. Esses arquivos são criados com extensões .pfx e/ou .p12. Esses arquivos são geralmente usados para importar e exportar certificados em máquinas Windows e MacOS.

Com o comando openssl podemos gerar certificados no formato PKCS#12 diretamente da CLI do Linux:

$ openssl pkcs12 -export -out certificado.pfx \
-inkey chaveprivada.key -in certificado.crt \
-certfile intermediario.crt

Sendo:

  • pkcs12 - o utilitário de arquivo para arquivos PKCS#12 em OpenSSL;
  • -export -out certificado.pfx - exportar e salvar o arquivo PKCS#12 com o nome certificado.pfx;
  • -inkey chaveprivada.key - use o arquivo de chave privada chaveprivada.key como a chave privada a ser combinada com o certificado;
  • -in certificado.crt - use o arquivo certificado.crt como o certificado com a qual a chave privada será combinada;
  • -certfile intermediario.crt - essa parte é opcional, serve para incluir quaisquer certificados adicionais que você queira incluir no arquivo PKCS#12.

Ao inserir o comando será solicitada uma senha de exportação para proteger o arquivo PKCS#12, isso é importante pois nesse arquivo constam o certificado e a chave privada. Essa chave será solicitada sempre que o arquivo for importado, portanto ela deve ser anotada.

Testando se a chave privada casa com o certificado ou com o CSR

Na criptografia de chave pública RSA, as chaves pública e privada de um par são matematicamente relacionadas, pois compartilham o mesmo módulo. O comprimento do módulo, expresso em bits, é o comprimento da chave.

Para confirmar se uma chave privada específica corresponde à chave contida em uma solicitação de assinatura de certificado e/ou um certificado, é preciso confirmar que os módulos de ambas as chaves são idênticos. Isso pode ser feito diretamente com o comando openssl.

Para visualizar o hash md5 do módulo da chave privada:

openssl rsa -noout -modulus -in chaveprivada.key | openssl md5

Para visualizar o hash md5 do módulo do CSR:

openssl req -noout -modulus -in requisicao.csr | openssl md5

Para visualizar o hash md5 do módulo do certificado:

openssl x509 -noout -modulus -in mycert.crt | openssl md5

Se as hash da chave e do certificado ou do CSR corresponderem quer dizer que há compatibilidade.

Além da verificação visual lendo as hash podemos usar o comando diff para comparar-las:

┌─[jeremias@lab-lpi2]──[23:59]──[/tmp/certificado]
└─[1004]─>$ openssl rsa -noout -modulus -in chaveprivada.key | openssl md5 > privkey-mod.txt
┌─[jeremias@lab-lpi2]──[00:00]──[/tmp/certificado]
└─[1005]─>$ openssl x509 -noout -modulus -in certificado.crt | openssl md5 > cert-mod.txt
┌─[jeremias@lab-lpi2]──[00:01]──[/tmp/certificado]
└─[1006]─>$ openssl req -noout -modulus -in requisicao.csr | openssl md5 > req-mod.txt
┌─[jeremias@lab-lpi2]──[00:10]──[/tmp/certificado]
└─[1007]─>$ diff3 req-mod.txt cert-mod.txt privkey-mod.txt 
┌─[jeremias@lab-lpi2]──[00:11]──[/tmp/certificado]
└─[1008]─>$ diff req-mod.txt privkey-mod.txt 
┌─[jeremias@lab-lpi2]──[00:11]──[/tmp/certificado]
└─[1010]─>$ diff cert-mod.txt privkey-mod.txt
Gerando um novo CSR a partir da chave privada e de um certificado preexistente

Eventualmente pode ser necessário criar um novo arquivo de requisição de certificado, como por exemplo quando um certificado está a expirar e precisamos renová-lo. Nessas situações pode ser interessante gerar um CSR a partir de um certificado preexistente pois dessa forma não precisaremos preencher manualmente todos os dados necessários ao certificado (pois eles encontran-se dentro do certificado antigo).

$ openssl x509 \
-in certificado-antigo.crt \
-sigkey chaveprivada.key \
-x509toreq -out requisicao.csr

Como o SSL funciona na relação cliente servidor

  1. Tal como mostrado na seção Secure Socket Layer a comunicação se inicia pelo client solicitando a página por um meio não criptografado (porta 80).
  2. Recebendo então como resposta o certificado do Webserver.
  3. O navegador do cliente faz a validação desse certificado utilizando as informações que constam no certificado sobre a CA que o emitiu.
  4. Se forem válidas ele:
    • Gerará um novo par de chaves pública/privada para uso próprio;
    • Armazenará na "chave de seção" a chave privada que acabou de gerar;
    • Armazenará a chave pública que consta no certificado do servidor como uma "chave de seção".
  5. Utilizando a chave pública armazenada na "chave de seção" em conjunto com o gerador de dados aleatórios do sistema /etc/random o cliente inicia uma comunicação criptografada com o Webserver enviando para ele sua chave pública e a solicitação de dados da página.
  6. Após os dados serem descriptografados usando a chave privada do servidor o webserver terá a chave pública do cliente que é armazenada na "chave de seção" e envia a solicitação do cliente para o "input data" da página.
  7. O webserver analisa a solicitação do cliente entregue em Input data e agora de posse da chave pública gerada pelo cliente armazenada em sua "chave de seção", responde a solicitação do cliente criptografando os dados a serem enviados utilizando o seu gerador de dados aleatórios /dev/random/ em conjunto com a chave pública recebida pelo usuário.
  8. Os dados são enviados criptografados para o cliente;
  9. Usando a chave privada que foi gerada anteriormente e que está armazenada em sua "chave de seção" o cliente consegue descriptografar os dados e enviá-los ao navegador.
  10. Mediante solicitação do usuário o navegador pode reiniciar o ciclo. Porém agora com "uma seção aberta" isto é, com todo esse processo de troca de chaves já executado.

Sorry, your browser does not support SVG.

Figura 8: Fluxo de comunicação HTTPS (troca de chaves)

Aplicando o SSL no Apache - Módulo mod_ssl

O módulo responsável por prover comunicação encriptografada no Apache é o mod_ssl hoje em dia ele já vem disponível no pacote de instalação padrão do Apache. Antes ele era distribuído como um pacote separado, o pacote continha:

  • O próprio módulo (mod_ssl.so);
  • Os arquivos de configuração necessários.
Diretivas do apache para o SSL

O mod_ssl tem diretivas específicas para trabalhar com o SSL:

SSLCertificateFile
O nome do arquivo que contém o certificado digital;
SSLCertificateKeyFile
O nome do arquivo que contém a chave privada;
SSLCypherSuite
Especifica o algoritmo de criptografia que o navegador pode usar;
SSLEngine (on/off)
Habilita ou desabilita o SSL (geralmente usado dentro da seção de um VirtualHost).
SSLEnable
É um alias para SSLEngine on;
SSLRequire
Suporta controle de acesso baseado em múltiplas variáveis de servidor.

Se todos os procedimentos que executamos até aqui foram bem sucedidos (criação da chave privada, criação e envio do CSR para a CA e recebimento do certificado da CA). Teremos dois arquivos importantes em mãos. A chave privada e o certificado emitido pela CA.

Copie os arquivos para um local definitivo, como por exemplo /etc/ssl/.

Em um servidor rodando CentOS, após instalado o suporte ao SSL, será criado o arquivo /etc/htpd/conf.d/ssl.conf. Nele haverá as configurações básicas de funcionamento do SSL.

Em uma configuração simplificada (sem usar VirtualHost) poderíamos procurar as diretivas que citamos acima e editá-las colocando os caminhos para os arquivos de chave e certificado, também executando os demais ajustes que forem necessários (SSLEnable e aí por diante).

Certificados auto-assinados

Além de ser um dos conhecimentos chave desse protocolo, saber criar uma CA própria para publicar certificados auto-assinados é uma necessidade que eventualmente aparece no dia a dia de um administrador de infraestrutura.

Assim o uso certificado auto-assinado irá criptografar corretamente a comunicação entre seu servidor e qualquer cliente. Porém como ele não tem a assinatura de nenhuma das Autoridades Certificadoras oficiais, um usuário "terceiro" receberá um alerta na tela do navegador informando que a autenticidade do certificado e, por consequência, de seu site não pode ser comprovada.

Porém um certificado auto-assinado pode ser útil para em ambientes como uma rede local, onde faz-se necessário publicar algo via webserver e não se quer que essa informação trafegue descriptografada mesmo na rede local. Nesse cenário é possível contornar a situação do alerta de autenticidade mostrado no navegador, copiando a chave pública da CA gerada e distribuindo ela nos computadores da rede local. Assim eles confiarão no seu site. Essa atividade pode ser automatizada utilizando GPOs de Windows, ou até mesmo criando tanto a CA quanto os certificados através do AD do local.

Criando uma CA e seus certificados no Linux

Quando o administrador precisa ter sua própria CA ele irá se responsabilizar por todo o workflow de geração dos certificados. Iniciando-se pela geração da chave privada da CA. Que é executada com o comando openssl:

openssl genrsa -des3 -out ca.key 4096

Como estamos criando uma chave para a CA é de fundamental importância que ela tenha uma senha, portanto usamos o parâmetro -des que fará com que ao executar o comando seja solicitada uma senha, depois solicitará sua confirmação. Guarde essa senha pois ela será necessária para a emissão dos seus certificados.

Após cria-se o certificado X509 da CA, este certificado conterá as informações necessárias para a validação da CA e sua chave pública:

openssl req -new -x509 -days 3650 -key ca.key -out ca.crt

Ao executar o comando ele solicitará a senha que criamos acima, depois solicitará dados como abreviatura de País, Estado, Cidade, nome da organização e afins. São essas informações que estarão contidas no certificado juntamente com a chave pública.

Para auditar o conteúdo do certificado gerado utiliza-se o comando:

openssl x509 -in ca.crt -text onde ca.crt é o nome do certificado a inspecionar.

Agora cria-se o certificado que será instalado no servidor propriamente dito. Assim repetiremos os passos executados acima. Primeiramente criaremos uma chave privada, note que para o servidor ter uma senha para a chave privada pode não ser prático, pois ela será solicitada sempre que precisarmos reiniciar o Apache, portanto aqui no nosso laboratório removeremos a opção -des:

openssl genrsa -out servidor.key

Agora geraremos o Certificate Signing Request (CSR) para que possamos requisitar à nossa CA a assinatura de um certificado. Lembre-se do que já vimos anteriormente o CSR é composto por uma chave pública concatenado com as informações do nosso site e ou serviço:

openssl req -new -key servidor.key -out servidor.csr

Se ficar duvidoso quanto a geração do CSR o conteúdo dele pode ser validado com o comando:

openssl req -in servidor.csr -text onde servidor.csr é o CSR a ser validado

Agora com o CSR podemos assinar ele com nossa CA:

openssl x509 -req -days 365 -in servidor.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out servidor.crt

Durante a execução será solicitada a senha da chave da CA e por fim será emitido o certificado. Note que como executamos todos os comandos sem executar caminhos todos os arquivos que geramos até aqui estarão dentro do diretório corrente:

ls -l
total 20
-rw-rw-r-- 1 usuario usuario 2183 mar 25 22:54 ca.crt
-rw------- 1 usuario usuario 3311 mar 25 22:49 ca.key
-rw-rw-r-- 1 usuario usuario 2045 mar 25 23:18 servidor.crt
-rw-rw-r-- 1 usuario usuario 1781 mar 25 23:07 servidor.csr
-rw------- 1 usuario usuario 3243 mar 25 23:07 servidor.key

Se você chegou até aqui e não tiver cinco arquivos novos no seu diretório reveja os passos.

Agora é só aplicar os certificados no seu Apache da mesma forma que faria com um certificado pago.

E como já exposto no tópico anterior, se não quiser alertas de autenticidade nos navegadores dos seus usuários instale o certificado da CA nesses navegadores.

Gerando certificados auto-assinados no Linux

Se não quiser se criar certificados para vários servidores, mas apenas emitir um certificado para um caso específico pode-se trabalhar com certificados-autoassinados que são assim chamados por não haver uma CA assinando por ele.

Portanto novamente usamos o comando openssl que nessa sintaxe criará tanto a chave privada quanto o certificado:

openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout exemplo.key -out exemplo.crt

Agora valide o certificado criado:

openssl x509 -in exemplo.crt -text

Por fim aponte o certificado e a respectiva chave no apache conforme já executamos anteriormente. Lembrando que como nesse caso não criamos uma CA quando o navegador apresentar o alerta de autenticidade o usuário deverá apenas aceitar isso no botão devido na tela de alerta do navegador.

Problemas do SSL com VirtualHosts

O problema de usar SSL em sites hospedados em VirtualHosts baseados em nome é que os VirtualHosts precisam saber qual hostname está sendo solicitado e essa solicitação não pode ser lida até que a conexão SSL seja estabelecida.

O comportamento normal, então, é que a conexão SSL seja configurada usando a configuração no host virtual padrão para o endereço onde a conexão foi recebida.

Apesar de o Apache poder renegociar a conexão SSL, depois de ver o nome do host na solicitação (e o faz), acaba sendo tarde demais para escolher o certificado do servidor correto a ser usado para corresponder ao nome do host da solicitação durante o handshake inicial, resultando em avisos e erros do navegador sobre certificados tendo o hostname errado neles.

Apesar de hoje em dia ser possível criar um certificado que inclua vários hostnames e até mesmo certificados wildcard que abrangem um domínio todo. Em alguns casos o uso destes pode não ser possível.

Mitigando o problema com o SNI

O Server Name Indication (SNI) ou "Indicação de Nome de Servidor", em tradução nossa, é uma extensão do protocolo SSL conforme a RFC 4366 que permite ao cliente incluir o hostname na primeira mensagem do handshake do SSL (connection setup). Assim permite-se ao webserver determinar o VirtualHost correto para a requisição.

Com o SNI, podem haver vários VirtualHost compartilhando o mesmo endereço de IP e porta e cada um com seu próprio certificado.

Data: 2021-03-22 seg 00:00

Autor: Jeremias Alves Queiroz

Criado em: 2021-12-17 sex 18:37

Valid XHTML 1.0 Strict