@ -14,38 +14,186 @@ Para aprender o básico de HTTPS de uma perspectiva do usuário, verifique <a hr
Agora, a partir de uma perspectiva do desenvolvedor, aqui estão algumas coisas para ter em mente ao pensar em HTTPS:
* Para HTTPS, o servidor precisa ter certificados gerados por um terceiro.
* Esses certificados são adquiridos de um terceiro, eles não são simplesmente "gerados".
* Certificados têm um tempo de vida.
* Eles expiram.
* E então eles precisam ser renovados, adquirindo-os novamente de um terceiro.
* A criptografia da conexão acontece no nível TCP.
* Essa é uma camada abaixo do HTTP.
* Portanto, o manuseio do certificado e da criptografia é feito antes do HTTP.
* O TCP não sabe sobre "domínios". Apenas sobre endereços IP.
* As informações sobre o domínio solicitado vão nos dados HTTP.
* Os certificados HTTPS “certificam” um determinado domínio, mas o protocolo e a encriptação acontecem ao nível do TCP, antes de sabermos de que domínio se trata.
* Por padrão, isso significa que você só pode ter um certificado HTTPS por endereço IP.
* Para HTTPS, **o servidor** precisa ter certificados gerados por **um terceiro**.
* Esses certificados são na verdade **adquiridos** de um terceiro, eles não são simplesmente "gerados".
* Certificados têm um **tempo de vida**.
* Eles **expiram**.
* E então eles precisam ser **renovados**, **adquirindo-os novamente** de um terceiro.
* A criptografia da conexão acontece no **nível TCP**.
* Essa é uma camada **abaixo do HTTP**.
* Portanto, o manuseio do **certificado e da criptografia** é feito **antes do HTTP**.
* **O TCP não sabe sobre "domínios"**. Apenas sobre endereços IP.
* As informações sobre o **domínio solicitado** vão nos **dados HTTP**.
* Os **certificados HTTPS** “certificam” um **determinado domínio**, mas o protocolo e a encriptação acontecem ao nível do TCP, **antes de sabermos** de que domínio se trata.
* **Por padrão**, isso significa que você só pode ter **um certificado HTTPS por endereço IP**.
* Não importa o tamanho do seu servidor ou quão pequeno cada aplicativo que você tem nele possa ser.
* No entanto, existe uma solução para isso.
* Há uma extensão para o protocolo TLS (aquele que lida com a criptografia no nível TCP, antes do HTTP) chamado <ahref="https://en.wikipedia.org/wiki/Server_Name_Indication"class="external-link"target="_blank"><abbrtitle="Server Name Indication">SNI</abbr></a>.
* Esta extensão SNI permite que um único servidor (com um único endereço IP) tenha vários certificados HTTPS e atenda a vários domínios / aplicativos HTTPS.
* Para que isso funcione, um único componente (programa) em execução no servidor, ouvindo no endereço IP público, deve ter todos os certificados HTTPS no servidor.
* Depois de obter uma conexão segura, o protocolo de comunicação ainda é HTTP.
* Os conteúdos são criptografados, embora sejam enviados com o protocolo HTTP.
* No entanto, existe uma **solução** para isso.
* Há uma **extensão** para o protocolo **TLS** (aquele que lida com a criptografia no nível TCP, antes do HTTP) chamado **<ahref="https://en.wikipedia.org/wiki/Server_Name_Indication"class="external-link"target="_blank"><abbrtitle="Server Name Indication">SNI</abbr></a>**.
* Esta extensão SNI permite que um único servidor (com um **único endereço IP**) tenha **vários certificados HTTPS** e atenda a **vários domínios / aplicativos HTTPS**.
* Para que isso funcione, um **único** componente (programa) em execução no servidor, ouvindo no **endereço IP público**, deve ter **todos os certificados HTTPS** no servidor.
* **Depois** de obter uma conexão segura, o protocolo de comunicação **ainda é HTTP**.
* Os conteúdos são **criptografados**, embora sejam enviados com o **protocolo HTTP**.
É uma prática comum ter um programa/servidor HTTP em execução no servidor (máquina, host, etc.) e gerenciar todas as partes HTTPS: enviando as solicitações HTTP descriptografadas para o aplicativo HTTP real em execução no mesmo servidor (a aplicação **FastAPI**, neste caso), pegue a resposta HTTP do aplicativo, criptografe-a usando o certificado apropriado e envie-a de volta ao cliente usando HTTPS. Este servidor é frequentemente chamado de <ahref="https://en.wikipedia.org/wiki/TLS_termination_proxy"class="external-link"target="_blank">TLS Termination Proxy</a>.
É uma prática comum ter um **programa/servidor HTTP** em execução no servidor (máquina, host, etc.) e **gerenciar todas as partes HTTPS**: **recebendo as requisições encriptadas**, enviando as **solicitações HTTP descriptografadas** para o aplicativo HTTP real em execução no mesmo servidor (a aplicação **FastAPI**, neste caso), pegue a **resposta HTTP** do aplicativo, **criptografe-a** usando o **certificado HTTPS** apropriado e envie-a de volta ao cliente usando **HTTPS**. Este servidor é frequentemente chamado de **<ahref="https://en.wikipedia.org/wiki/TLS_termination_proxy"class="external-link"target="_blank">Proxy de Terminação TLS</a>**.
Algumas das opções que você pode usar como Proxy de Terminação TLS são:
* Traefik (que também pode gerenciar a renovação de certificados)
* Caddy (que também pode gerenciar a renovação de certificados)
* Nginx
* HAProxy
## Let's Encrypt
Antes de Let's Encrypt, esses certificados HTTPS eram vendidos por terceiros confiáveis.
Antes de Let's Encrypt, esses **certificados HTTPS** eram vendidos por terceiros confiáveis.
O processo de aquisição de um desses certificados costumava ser complicado, exigia bastante papelada e os certificados eram bastante caros.
Mas então <ahref="https://letsencrypt.org/"class="external-link"target="_blank">Let's Encrypt</a> foi criado.
Mas então o **<ahref="https://letsencrypt.org/"class="external-link"target="_blank">Let's Encrypt</a>** foi criado.
Ele é um projeto da Linux Foundation que fornece certificados HTTPS gratuitamente. De forma automatizada. Esses certificados usam toda a segurança criptográfica padrão e têm vida curta (cerca de 3 meses), então a segurança é realmente melhor por causa de sua vida útil reduzida.
Ele é um projeto da Linux Foundation que fornece **certificados HTTPS gratuitamente**. De forma automatizada. Esses certificados usam toda a segurança criptográfica padrão e têm vida curta (cerca de 3 meses), então a **segurança é, na verdade, melhor** por causa de sua vida útil reduzida.
Os domínios são verificados com segurança e os certificados são gerados automaticamente. Isso também permite automatizar a renovação desses certificados.
A ideia é automatizar a aquisição e renovação desses certificados, para que você tenha HTTPS seguro, de graça e para sempre.
A ideia é automatizar a aquisição e renovação desses certificados, para que você tenha **HTTPS seguro, de graça e para sempre**.
## HTTPS para Desenvolvedores
Aqui está um exemplo de como uma API HTTPS poderia ser estruturada, passo a passo, com foco principal nas ideias relevantes para desenvolvedores.
### Nome do domínio
A etapa inicial provavelmente seria **adquirir** algum **nome de domínio**. Então, você iria configurá-lo em um servidor DNS (possivelmente no mesmo provedor em nuvem).
Você provavelmente usaria um servidor em nuvem (máquina virtual) ou algo parecido, e ele teria <abbrtitle="Que não muda">fixed</abbr>**Endereço IP público**.
No(s) servidor(es) DNS, você configuraria um registro (`registro A`) para apontar **seu domínio** para o **endereço IP público do seu servidor**.
Você provavelmente fará isso apenas uma vez, na primeira vez em que tudo estiver sendo configurado.
/// tip | Dica
Essa parte do Nome do Domínio se dá muito antes do HTTPS, mas como tudo depende do domínio e endereço IP público, vale a pena mencioná-la aqui.
///
### DNS
Agora vamos focar em todas as partes que realmente fazem parte do HTTPS.
Primeiro, o navegador iria verificar com os **servidores DNS** qual o **IP do domínio**, nesse caso, `someapp.example.com`.
Os servidores DNS iriam informar o navegador para utilizar algum **endereço IP** específico. Esse seria o endereço IP público em uso no seu servidor, que você configurou nos servidores DNS.
<imgsrc="/img/deployment/https/https01.svg">
### Início do Handshake TLS
O navegador então irá comunicar-se com esse endereço IP na **porta 443** (a porta HTTPS).
A primeira parte dessa comunicação é apenas para estabelecer a conexão entre o cliente e o servidor e para decidir as chaves criptográficas a serem utilizadas, etc.
<imgsrc="/img/deployment/https/https02.svg">
Esse interação entre o cliente e o servidor para estabelecer uma conexão TLS é chamada de **Handshake TLS**.
### TLS com a Extensão SNI
**Apenas um processo** no servidor pode se conectar a uma **porta** em um **endereço IP**. Poderiam existir outros processos conectados em outras portas desse mesmo endereço IP, mas apenas um para cada combinação de endereço IP e porta.
TLS (HTTPS) usa a porta `443` por padrão. Então essa é a porta que precisamos.
Como apenas um único processo pode se comunicar com essa porta, o processo que faria isso seria o **Proxy de Terminação TLS**.
O Proxy de Terminação TLS teria acesso a um ou mais **certificados TLS** (certificados HTTPS).
Utilizando a **extensão SNI** discutida acima, o Proxy de Terminação TLS iria checar qual dos certificados TLS (HTTPS) disponíveis deve ser usado para essa conexão, utilizando o que corresponda ao domínio esperado pelo cliente.
Nesse caso, ele usaria o certificado para `someapp.example.com`.
<imgsrc="/img/deployment/https/https03.svg">
O cliente já **confia** na entidade que gerou o certificado TLS (nesse caso, o Let's Encrypt, mas veremos sobre isso mais tarde), então ele pode **verificar** que o certificado é válido.
Então, utilizando o certificado, o cliente e o Proxy de Terminação TLS **decidem como encriptar** o resto da **comunicação TCP**. Isso completa a parte do **Handshake TLS**.
Após isso, o cliente e o servidor possuem uma **conexão TCP encriptada**, que é provida pelo TLS. E então eles podem usar essa conexão para começar a **comunicação HTTP** propriamente dita.
E isso resume o que é **HTTPS**, apenas **HTTP** simples dentro de uma **conexão TLS segura** em vez de uma conexão TCP pura (não encriptada).
/// tip | Dica
Percebe que a encriptação da comunicação acontece no **nível do TCP**, não no nível do HTTP.
///
### Solicitação HTTPS
Agora que o cliente e servidor (especialmente o navegador e o Proxy de Terminação TLS) possuem uma **conexão TCP encriptada**, eles podem iniciar a **comunicação HTTP**.
Então, o cliente envia uma **solicitação HTTPS**. Que é apenas uma solicitação HTTP sobre uma conexão TLS encriptada.
<imgsrc="/img/deployment/https/https04.svg">
### Desencriptando a Solicitação
O Proxy de Terminação TLS então usaria a encriptação combinada para **desencriptar a solicitação**, e transmitiria a **solicitação básica (desencriptada)** para o processo executando a aplicação (por exemplo, um processo com Uvicorn executando a aplicação FastAPI).
<imgsrc="/img/deployment/https/https05.svg">
### Resposta HTTP
A aplicação processaria a solicitação e retornaria uma **resposta HTTP básica (não encriptada)** para o Proxy de Terminação TLS.
<imgsrc="/img/deployment/https/https06.svg">
### Resposta HTTPS
O Proxy de Terminação TLS iria **encriptar a resposta** utilizando a criptografia combinada anteriormente (que foi definida com o certificado para `someapp.example.com`), e devolveria para o navegador.
No próximo passo, o navegador verifica que a resposta é válida e encriptada com a chave criptográfica correta, etc. E depois **desencripta a resposta** e a processa.
<imgsrc="/img/deployment/https/https07.svg">
O cliente (navegador) saberá que a resposta vem do servidor correto por que ela usa a criptografia que foi combinada entre eles usando o **certificado HTTPS** anterior.
### Múltiplas Aplicações
Podem existir **múltiplas aplicações** em execução no mesmo servidor (ou servidores), por exemplo: outras APIs ou um banco de dados.
Apenas um processo pode estar vinculado a um IP e porta (o Proxy de Terminação TLS, por exemplo), mas outras aplicações/processos também podem estar em execução no(s) servidor(es), desde que não tentem usar a mesma **combinação de IP público e porta**.
<imgsrc="/img/deployment/https/https08.svg">
Dessa forma, o Proxy de Terminação TLS pode gerenciar o HTTPS e os certificados de **múltiplos domínios**, para múltiplas aplicações, e então transmitir as requisições para a aplicação correta em cada caso.
### Renovação de Certificados
Em algum momento futuro, cada certificado irá **expirar** (aproximadamente 3 meses após a aquisição).
E então, haverá outro programa (em alguns casos pode ser o próprio Proxy de Terminação TLS) que irá interagir com o Let's Encrypt e renovar o(s) certificado(s).
<imgsrc="/img/deployment/https/https.svg">
Os **certificados TLS** são **associados com um nome de domínio**, e não a um endereço IP.
Então para renovar os certificados, o programa de renovação precisa **provar** para a autoridade (Let's Encrypt) que ele realmente **possui e controla esse domínio**>
Para fazer isso, e acomodar as necessidades de diferentes aplicações, existem diferentes opções para esse programa. Algumas escolhas populares são:
* **Modificar alguns registros DNS**
* Para isso, o programa de renovação precisa ter suporte as APIs do provedor DNS, então, dependendo do provedor DNS que você utilize, isso pode ou não ser uma opção viável.
* **Executar como um servidor** (ao menos durante o processo de aquisição do certificado) no endereço IP público associado com o domínio.
* Como dito anteriormente, apenas um processo pode estar ligado a uma porta e IP específicos.
* Essa é uma dos motivos que fazem utilizar o mesmo Proxy de Terminação TLS para gerenciar a renovação de certificados ser tão útil.
* Caso contrário, você pode ter que parar a execução do Proxy de Terminação TLS momentaneamente, inicializar o programa de renovação para renovar os certificados, e então reiniciar o Proxy de Terminação TLS. Isso não é o ideal, já que sua(s) aplicação(ões) não vão estar disponíveis enquanto o Proxy de Terminação TLS estiver desligado.
Todo esse processo de renovação, enquanto o aplicativo ainda funciona, é uma das principais razões para preferir um **sistema separado para gerenciar HTTPS** com um Proxy de Terminação TLS em vez de usar os certificados TLS no servidor da aplicação diretamente (e.g. com o Uvicorn).
## Recapitulando
Possuir **HTTPS** habilitado na sua aplicação é bastante importante, e até **crítico** na maioria dos casos. A maior parte do esforço que você tem que colocar sobre o HTTPS como desenvolvedor está em **entender esses conceitos** e como eles funcionam.
Mas uma vez que você saiba o básico de **HTTPS para desenvolvedores**, você pode combinar e configurar diferentes ferramentas facilmente para gerenciar tudo de uma forma simples.
Em alguns dos próximos capítulos, eu mostrarei para você vários exemplos concretos de como configurar o **HTTPS** para aplicações **FastAPI**. 🔒