Por que um servidor 443 default_server; regra nginx substituir regra já configurada (regras http funcionando normalmente)?

9

Eu tenho um nginx e subdomínios diferentes:

a.mydomain.com
b.mydomain.com
c.mydomain.com

O Nginx possui 4 regras:

1) regra de reescrita:

server {
  listen 80
  server_name gl.udesk.org;

  root /nowhere;
  rewrite ^ https://a.mydomain.com$request_uri permanent;
}

2) regra https:

server {

  listen 443;
  server_name a.mydomain.com;

  root /home/a/a/public;

  ssl on;
  ssl_certificate conf.d/ssl/a.crt;
  ssl_certificate_key conf.d/ssl/a.key;
  ssl_protocols ...
  ssl_ciphers ...
  ssl_prefer_server_ciphers on;

  location ...
}

3) regra padrão http:

server {
  listen 80 default_server;
  return 444;
}

4) https regra padrão:

server {
  listen 443 default_server;
  return 444;
}

Então, se eu iniciar o nginx e:

  • se eu for no navegador para http://a.mydomain.com, ele será redirecionado para https://a.mydomain.com e, em seguida, retornará um erro 107 (net :: ERR_SSL_PROTOCOL_ERROR): protocolo SSL.
  • se eu for no https://b.mydomain.com no navegador, espero que ele retorne o erro 444 de volta. Mas, em vez disso, ele retorna o mesmo erro 107 (net :: ERR_SSL_PROTOCOL_ERROR): erro de protocolo SSL.
  • e assim, para todos registrados pelo provedor de DNS CNAMEs (ou seja, a, b, c)
  • todas as versões http (por exemplo, regra 3 -) funcionando conforme o esperado:

Então, por que as regras https no nginx são tão difíceis de configurar e como devo configurá-las corretamente para obter o mesmo comportamento da versão http?

Atualizar:

Criando um novo certificado e adicionando:

ssl on;
ssl_certificate conf.d/ssl/default.crt;
ssl_certificate_key conf.d/ssl/default.key;

funciona agora, mas eu teria uma solução sem nenhum certificado SSL necessário. Redefina todas as conexões para todos os subdomínios https (porta 443), exceto https://a.mydomain.com sem fornecer um certificado.

estático
fonte
2
Você não pode. O SSL requer um certificado antes que o servidor da Web saiba qual domínio você deseja . Ele precisa ter um certificado para enviar ou não pode estabelecer a conexão para conversar com o cliente.
Darth Android
2
@DarthAndroid: A mágica é chamada SNI - en.wikipedia.org/wiki/Server_Name_Indication .
Shi
@Shi Estou ciente do SNI - Isso permite que o servidor da Web escolha qual certificado enviar, mas ainda deve escolher um certificado. nginxnão é inteligente o suficiente para perceber que não precisa de um certificado para o que o usuário deseja fazer.
Darth Android

Respostas:

3

Não misture a porta 443 com o ssl! O Nginx é completamente independente de porta. Você também pode oferecer https através da porta 80. As versões modernas do nginx permitem

listen 1234 ssl;

e você não precisa da ssl on;linha então.

Mas se você deseja exibir https, precisará especificar um certificado. Seu servidor insere https quando reescreve a solicitação http em uma solicitação https.

Você obtém o erro de protocolo, pois o handshake SSL é feito antes de qualquer outra coisa. Então return 444não é alcançado. E qualquer SSL Handshake precisará de um certificado e uma chave privada, para alimentar os algoritmos de criptografia com o par de certificado / chave privada.

ikrabbe
fonte
3

A returndiretiva faz parte do módulo de reescrita. Se você verificar a documentação , poderá ver que ela funciona com solicitações. Em HTTPS, as solicitações só podem ser feitas após a conclusão do handshake.

Há uma solicitação de recurso: https://trac.nginx.org/nginx/ticket/195 e uma solução alternativa é fornecida.

server {
    listen 443 ssl;
    server_name bbb.example.com;
    ssl_ciphers aNULL;
    ssl_certificate /path/to/dummy.crt;
    ssl_certificate_key /path/to/dummy.key;
    return 444;
}
VBart
fonte
Observe isso vai quebrar clientes HTTPS não-SNI-capazes (como nginx própria proxy_pass, a menos que você definir proxy_ssl_server_name on;) de alcançar qualquer outro server_names(tão essencialmente quebrar as legítimas server_names que você não quer deixar passar). Consulte trac.nginx.org/nginx/ticket/195#comment:11 para obter detalhes.
NH2