<!-- review: finished -->

<a id="ssl-config"></a>

# Configuração SSL

Para configurar um servidor HTTPS, o parâmetro [ssl](https://pt.angie.software//angie/docs/configuration/modules/http/index.md#listen) deve ser habilitado
nos sockets de escuta no bloco [server](https://pt.angie.software//angie/docs/configuration/modules/http/index.md#server), e as localizações dos arquivos de
certificado do servidor e chave privada devem ser especificadas:

```nginx
server {
    listen              443 ssl;
    server_name         www.example.com;
    ssl_certificate     www.example.com.crt;
    ssl_certificate_key www.example.com.key;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         HIGH:!aNULL:!MD5;
#...
}
```

O certificado do servidor é uma entidade pública. Ele é enviado para todo cliente que
se conecta ao servidor. A chave privada é uma entidade segura e deve ser armazenada
em um arquivo com acesso restrito; no entanto, deve ser legível pelo processo
mestre do Angie. A chave privada pode alternativamente ser armazenada no mesmo arquivo
do certificado.

```nginx
ssl_certificate     www.example.com.cert;
ssl_certificate_key www.example.com.cert;
```

Neste caso, os direitos de acesso ao arquivo também devem ser restritos. Embora o
certificado e a chave sejam armazenados em um arquivo, apenas o certificado é enviado
para o cliente.

As diretivas [ssl_protocols](https://pt.angie.software//angie/docs/configuration/modules/http/http_ssl.md#ssl-protocols) e [ssl_ciphers](https://pt.angie.software//angie/docs/configuration/modules/http/http_ssl.md#ssl-ciphers) podem ser usadas para limitar
conexões para incluir apenas as versões e cifras fortes do SSL/TLS. Por
padrão, o Angie usa:

```nginx
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
```

Portanto, configurá-las explicitamente geralmente não é necessário.

<a id="https-optimization"></a>

## Otimização do Servidor HTTPS

Operações SSL consomem recursos extras de CPU. Em sistemas multiprocessador, vários
[processos worker](https://pt.angie.software//angie/docs/configuration/modules/core.md#worker-processes) devem ser executados, não menos que o
número de núcleos de CPU disponíveis. A operação mais intensiva em CPU é o
handshake SSL. Há duas maneiras de minimizar o número dessas operações por
cliente: a primeira é habilitando conexões [keepalive](https://pt.angie.software//angie/docs/configuration/modules/http/index.md#keepalive-timeout)
para enviar várias requisições através de uma conexão, e a segunda é reutilizar
parâmetros de sessão SSL para evitar handshakes SSL para conexões paralelas e subsequentes.
As sessões são armazenadas em um cache de sessão SSL compartilhado entre
workers e configurado pela diretiva [ssl_session_cache](https://pt.angie.software//angie/docs/configuration/modules/http/http_ssl.md#ssl-session-cache). Um megabyte
do cache contém cerca de 4000 sessões. O timeout padrão do cache é 5
minutos. Pode ser aumentado usando a diretiva [ssl_session_timeout](https://pt.angie.software//angie/docs/configuration/modules/http/http_ssl.md#ssl-session-timeout).
Aqui está uma configuração de exemplo otimizada para um sistema multi-core com um
cache de sessão compartilhado de 10 megabytes:

```nginx
worker_processes auto;

http {
    ssl_session_cache   shared:SSL:10m;
    ssl_session_timeout 10m;

    server {
        listen              443 ssl;
        server_name         www.example.com;
        keepalive_timeout   70;

        ssl_certificate     www.example.com.crt;
        ssl_certificate_key www.example.com.key;
        ssl_protocols       TLSv1.2 TLSv1.3;
        ssl_ciphers         HIGH:!aNULL:!MD5;
    #...
```

<a id="certificate-chaining"></a>

## Cadeias de Certificados SSL

Alguns navegadores podem reclamar sobre um certificado assinado por uma autoridade
certificadora bem conhecida, enquanto outros navegadores podem aceitar o certificado sem
problemas. Isso ocorre porque a autoridade emissora assinou o certificado do servidor
usando um certificado intermediário que não está presente na
base de certificados de autoridades certificadoras confiáveis bem conhecidas distribuída com
um navegador específico. Neste caso, a autoridade fornece um pacote de certificados encadeados
que devem ser concatenados ao certificado do servidor assinado. O
certificado do servidor deve aparecer antes dos certificados encadeados no arquivo
combinado:

```console
$ cat www.example.com.crt bundle.crt > www.example.com.chained.crt
```

O arquivo resultante deve ser usado com a diretiva [ssl_certificate](https://pt.angie.software//angie/docs/configuration/modules/http/http_ssl.md#ssl-certificate):

```nginx
server {
    listen              443 ssl;
    server_name         www.example.com;
    ssl_certificate     www.example.com.chained.crt;
    ssl_certificate_key www.example.com.key;
#...
}
```

Se o certificado do servidor e o pacote foram concatenados na ordem errada,
o Angie falha ao iniciar e exibe uma mensagem de erro:

> SSL_CTX_use_PrivateKey_file(" ... /www.example.com.key") failed
> : (SSL: error:0B080074:x509 certificate routines:
>   X509_check_private_key:key values mismatch)

Porque o Angie tentou usar a chave privada com o primeiro
certificado do pacote em vez do certificado do servidor.

Navegadores geralmente armazenam certificados intermediários que recebem, assinados por
autoridades confiáveis, então navegadores que são realmente usados podem já ter os
certificados intermediários necessários e podem não reclamar sobre um certificado
sendo enviado sem um pacote encadeado. Para garantir que o servidor envie a cadeia
completa de certificados, o utilitário de linha de comando **openssl** pode ser usado, por
exemplo:

```console
$ openssl s_client -connect www.godaddy.com:443

Certificate chain
 0 s:/C=US/ST=Arizona/L=Scottsdale/1.3.6.1.4.1.311.60.2.1.3=US
     /1.3.6.1.4.1.311.60.2.1.2=AZ/O=GoDaddy.com, Inc
     /OU=MIS Department/CN=www.GoDaddy.com
     /serialNumber=0796928-7/2.5.4.15=V1.0, Clause 5.(b)
   i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc.
     /OU=http://certificates.godaddy.com/repository
     /CN=Go Daddy Secure Certification Authority
     /serialNumber=07969287
 1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc.
     /OU=http://certificates.godaddy.com/repository
     /CN=Go Daddy Secure Certification Authority
     /serialNumber=07969287
   i:/C=US/O=The Go Daddy Group, Inc.
     /OU=Go Daddy Class 2 Certification Authority
 2 s:/C=US/O=The Go Daddy Group, Inc.
     /OU=Go Daddy Class 2 Certification Authority
   i:/L=ValiCert Validation Network/O=ValiCert, Inc.
     /OU=ValiCert Class 2 Policy Validation Authority
     /CN=http://www.valicert.com//emailAddress=info@valicert.com
```

Neste exemplo, o assunto ("s") do certificado do servidor www.GoDaddy.com #0
é assinado por um emissor ("i") que é ele próprio o assunto do certificado #1,
que é assinado por um emissor que é ele próprio o assunto do certificado #2,
que é assinado pelo emissor bem conhecido ValiCert, Inc. cujo certificado está
armazenado na base de certificados integrada dos navegadores.

Se um pacote de certificados não foi adicionado, apenas o certificado do servidor #0 será
mostrado.

<a id="compact-server"></a>

## Um Único Servidor HTTP/HTTPS

É possível configurar um único servidor que manipula tanto requisições HTTP quanto HTTPS:

```nginx
server {
    listen              80;
    listen              443 ssl;
    server_name         www.example.com;
    ssl_certificate     www.example.com.crt;
    ssl_certificate_key www.example.com.key;
#...
}
```

<a id="name-based-https-servers"></a>

## Servidores HTTPS Baseados em Nome

Um problema comum surge ao configurar dois ou mais servidores HTTPS escutando em um
único endereço IP:

```nginx
server {
    listen          443 ssl;
    server_name     www.example.com;
    ssl_certificate www.example.com.crt;
#...
}

server {
    listen          443 ssl;
    server_name     www.example.org;
    ssl_certificate www.example.org.crt;
#...
}
```

Com esta configuração, um navegador recebe o certificado do servidor padrão,
ou seja, www.example.com, independentemente do nome do servidor solicitado. Isso é causado
pelo comportamento do protocolo SSL. A conexão SSL é estabelecida antes do navegador
enviar uma requisição HTTP, e o Angie não conhece o nome do servidor
solicitado. Portanto, ele só pode oferecer o certificado do servidor padrão.

<a id="https-separate-ips"></a>

O método mais antigo e robusto para resolver o problema é atribuir um endereço
IP separado para cada servidor HTTPS:

```nginx
server {
    listen          192.168.1.1:443 ssl;
    server_name     www.example.com;
    ssl_certificate www.example.com.crt;
#...
}

server {
    listen          192.168.1.2:443 ssl;
    server_name     www.example.org;
    ssl_certificate www.example.org.crt;
#...
}
```

<a id="an-ssl-certificate-with-multiple-names"></a>

## Um Certificado SSL com Múltiplos Nomes

Existem outras maneiras que permitem compartilhar um único endereço IP entre
vários servidores HTTPS. No entanto, todas elas têm suas desvantagens. Uma
maneira é usar um certificado com vários nomes no campo de certificado
`SubjectAltName`, por exemplo, `www.example.com` e `www.example.org`.
No entanto, o comprimento do campo `SubjectAltName` é limitado.

Outra maneira é usar um certificado com um nome curinga, por exemplo,
`*.example.org`. Um certificado curinga protege todos os subdomínios do
domínio especificado, mas apenas em um nível. Este certificado corresponde a
`www.example.org` mas não corresponde a `example.org` e
`www.sub.example.org`. Esses dois métodos também podem ser combinados. Um
certificado pode conter nomes exatos e curingas no campo `SubjectAltName`,
por exemplo, `example.org` e `*.example.org`.

É melhor colocar um arquivo de certificado com vários nomes e seu arquivo de
chave privada no nível `http` da configuração para herdar sua única cópia
de memória em todos os servidores:

```nginx
ssl_certificate     common.crt;
ssl_certificate_key common.key;

server {
    listen          443 ssl;
    server_name     www.example.com;
#...
}

server {
    listen          443 ssl;
    server_name     www.example.org;
#...
}
```

<a id="sni"></a>

## Indicação de Nome do Servidor

Uma solução mais genérica para executar vários servidores HTTPS em um único
endereço IP é a extensão TLS Server Name Indication (SNI, [RFC 6066](https://datatracker.ietf.org/doc/html/rfc6066.html)), que permite que um
navegador passe um nome de servidor solicitado durante o handshake SSL e,
portanto, o servidor saberá qual certificado deve usar para a conexão. O SNI é
atualmente suportado pela maioria dos navegadores modernos, embora possa não ser
usado por alguns clientes antigos ou especiais.

Se o Angie foi construído com suporte SNI, então o Angie mostrará isso quando
executado com a opção `-V`:

```console
$ angie -V
...
TLS SNI support enabled
...
```

No entanto, se o Angie habilitado para SNI estiver vinculado dinamicamente a uma
biblioteca OpenSSL sem suporte SNI, o Angie exibe um aviso:

> O Angie foi construído com suporte SNI, no entanto, agora está vinculado
> dinamicamente a uma biblioteca OpenSSL que não tem suporte tlsext,
> portanto SNI não está disponível
