Gerando certificados HTTPS com CERTBOT+Nginx

sexta-feira, 29 de março de 2019

Gerando certificados HTTPS com CERTBOT+Nginx


Bons Dias Jovens Padawans !

Como vocês estão ?
Treinado muito a força ?

Pessoal, seguindo a linha que tenho procurado trazer para vocês, ferramentas que ajudam os padawans de infra no dia a dia, hoje vou trazer para vocês um artigo interessante: Gerar certificados HTTPS com CERTBOT para nginx como proxy reverso.




Contextualizando


Como sempre, vamos imaginar uma situação aqui:
Nós temos um ambiente Docker, simples, porém cada serviço/aplicação do nosso ambiente Docker precisa de uma URL específica.
Por exemplo:
Tenho 1 Jfrog Artifactory OSS para meus artefatos, 1 aplicação Web do meu cliente e meu blog em wordpress. Cada um desses é um container, no mínimo.

  • O meu Jfrog Artifactory OSS precisa ter a URL como artifactory.keep-linux.ga.
  • A aplicação do meu cliente precisa ter uma URL como cliente.keep-linux.ga.
  • E por fim, meu blog precisa da URL blog.keep-linux.ga.
Por trás desses containeres eu tenho um proxy reverso, para facilitar meu manuseio com meu docker.
Para esta função, coloquei meu nginx para atuar como proxy reverso e encaminhar o tráfego de acordo com a URL que "bater" nele.


Mas O que é Proxy Reverso ?

Para a galera que não está acostumada com o termo, Proxy Reverso é basicamente um web server (apache httpd, nginx....) que recebe todo o tráfego web HTTP/HTTPS e redireciona a requisição que busca por uma certa URL para uma pasta específica do servidor ou um outro web server, ou seja, um upstream.

Um exemplo que ilustra bem, é a imagem abaixo:



Para que preciso de um certificado HTTPS ?

O protocolo HTTP conta com o S, de segurança. Ah vá, sério cara ?!
E para assegurar o seu browser (chrome, opera, firefox, safari) de que o servidor que está servindo aquele determinado site de forma segura e, principalmente, de que realmente é aquele servidor que deveria te servir o site procurado, o browser exige um certificado de segurança do servidor "assinado" por uma Autoridade Certificadora (CA).
Somente assim, o procotolo HTTPS pode ser efetivado.
Este certificado se trata, na mais básica forma, de um ou mais pares de chaves RSA geradas para esta comunicação.






Mão na massa !

Vamos por etapas, é um processo um pouco extenso.
Vamos assumir que você já possui os três containeres montados (up and running).
Vamos assumir que os containeres também já estão vinculados à um IP dentro de uma docker network.

Em nosso exemplo, vamos usar os seguintes IP's para os containeres na docker network:
  • JFrog Artifactory OSS - 172.80.238.10
  • Apache httpd (Aplicação Cliente) - 172.81.238.11
  • Blog WordPress - 172.81.238.12
Todo o processo é baseado em CentOS 7 ok pessoal ?


Pré-Requisitos

  • Instale o Nginx na máquina onde estão os containeres Docker (levando em consideração uma máquina standalone de Docker).
  • Instale o CertBot na mesma máquina em que o Nginx foi instalado:
    yum -y install epel-release
    yum -y install yum -utils
    yum -y install certbot
  • As URLs estão configuradas em seu domínio. (DNS)


Criando os registros de URL no nginx

Vá até a pasta /etc/nginx/conf.d/ e crie um arquivo de configuração para a URL artifactory.keep-linux.com.br (artifactory.conf).
Este arquivo de configuração precisa ter alguns headers definidos para que o proxy reverso seja habilitado e o SSL habilitado para o nginx. Não entraremos em questões de configurar o nginx especificamente.
Para simplificarmos ao máximo, pois cada um tem um padrão de configuração específico, segue abaixo um exemplo que pode ser utilizado para as três URL's.

server {
 listen 80;
 server_name artifactory.keep-linux.ga;
# Descomente este IF para redirecionar todo o tráfego HTTP para HTTPS
#    if ($host = artifactory.keep-linux.ga) {
#       return 301 https://$host$request_uri;
#    }

}

server {
  listen 443 ssl;
  client_max_body_size 100M;
  proxy_connect_timeout       600;
  proxy_send_timeout          600;
  proxy_read_timeout          600;
  send_timeout                600;
  server_name artifactory.keep-linux.ga;
  root /opt/www/html/;
  access_log  /var/log/nginx/artifactory.keep-linux.ga.access.log;
  error_log   /var/log/nginx/artifactory.keep-linux.ga.error.log;

  # Enable session resumption for better performance.
  ssl_session_cache shared:SSL:50m;
  ssl_session_timeout 5m;

  # SSLv1 and SSLv2 are unsecure and SSLv3 is weak! Use TLS only.
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

  # Force server to follow its cipher definitions.
  ssl_prefer_server_ciphers on;

  ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSAAES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4:!SSLv2";

  # SSL stapling. An internal resolver can be used instead.
  ssl_stapling off;
  ssl_stapling_verify off;

  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-Host $host;
  proxy_set_header X-Forwarded-Server $host;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_hide_header Pragma;
  proxy_hide_header Cache-Control;
  proxy_intercept_errors on;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";
  proxy_redirect http://$host/ https://$host/;
  proxy_cookie_path ~(.*)$ "$1; secure";

  location / {
    if ($request_uri ~* "^.+\.(?:cur|css|js|jpe?g|gif|htc|ico|png|html|xml|otf|ttf|eot|woff|svg)$") {
      access_log off;
      expires modified +24h;
      break;
    }
    proxy_pass http://artifactory.keep-linux.ga;
  }

  error_page 400 404 /404.html;
  error_page 500 502 504 /500.html;
  error_page 503 /503.html;

  location = /404.html { internal; }
  location = /500.html { internal; }
  location = /503.html { internal; }
}

upstream artifactory.keep-linux.ga {
  server 172.80.238.10:8081;
}

Se atente para esta última chave, upstream, ela indica para onde será efetuado o redirect das requisições, no caso, para nosso container e sua porta de trabalho.

Uma vez configurada a URL no arquivo de configuração, podemos realizar um reload no nginx, para leitura das novas URL's.

systemctl reload nginx

Gerando o certificado com CERTBOT


Realize o comando abaixo e siga o wizzard.
$ certbot --nginx
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org

Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: artifactory.keep-linux.ga
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 1
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for artifactory.keep-linux.ga
Waiting for verification...
Cleaning up challenges
Resetting dropped connection: acme-v02.api.letsencrypt.org
Deploying Certificate to VirtualHost /etc/nginx/sites.d/art.conf

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 1

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://artifactory.keep-linux.ga

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=artifactory.keep-linux.ga
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/artifactory.keep-linux.ga/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/artifactory.keep-linux.ga/privkey.pem
   Your cert will expire on 2019-06-23. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le
É um wizzard bem simples, onde o certbot lhe perguntará qual URL deseja gerar um certificado.
Haverá uma parte deste wizzard, após escolher a URL, onde será questionado se há a necessidade de se realizar um Redirect. Por via das dúvidas já foi adicionado este conteúdo em nosso arquivo de configuração, porém, comentado.

Ao final do wizzard, sua URL estará configurada com os certificados e já redirecionada para o container especificado.

O que o CertBot faz ?

O certbot é uma ferramenta certificadora que implementa um "challenge" em seu servidor para que a Autoridade Certificadora (CA) Let's Encrypt possa assinar e comprovar que o seu servidor realmente é quem diz ser e quem possui o domínio apontado no DNS para aquela URL.
Vai por mim, se você fosse implementar todo esse percurso de geração de challenge na unha, você ficaria bem doido antes de completar rsrs.

Renovando automaticamente meus certificados

Os certificados gerados pelo CertBot possuem uma validade de 3 meses. Por ser gratuito, não temos como aumentar este prazo de validade.
Quando realizamos nosso cadastro e informamos um email, recebemos com um mês de antecedência um email informando que o certificado para o domínio irá expirar.
Mas, afinal, estamos na era da automação, pra que se preocupar com isso a cada 2 meses né ?

Para renovar automaticamente nossos certificados, sem downtime, basta criarmos um registro em nosso crontab com a linha abaixo. De 2 em 2 meses executamos o comando
$ certbot renew --nginx
$ sudo vim /etc/crontab
# Insira as linhas abaixo no arquivo
# Rotina para renovar os certificados
0 8 * */2 * root certbot renew --nginx;

0 comentários :

Postar um comentário